From ba7302ec17359c9ba84c8f44a081993f7821b503 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Tue, 10 Nov 2026 22:28:52 +0900 Subject: [PATCH 01/13] The MSVC payload's C library is ucrt, as the MinGW payload's is The triple's env segment names the toolset on Windows, gnu and msvc alike; the C library of both is the Universal CRT. payload_libc_name answered `msvc` for an MSVC row, so `requires = ["mcpp:c-abi=ucrt"]` (compat.glfw's Win32 backend) refused the MSVC route while the GNU routes satisfied it. The request `msvc` is satisfied by `ucrt`. SPEC-002 v1.7 states the names; docs/22 (en, zh). --- docs/22-target-side.md | 4 +++- docs/specs/target-side.md | 8 +++++++- docs/zh/22-target-side.md | 4 +++- modules/manifest/src/targetside_model.cppm | 4 ++++ tests/unit/test_targetside.cpp | 7 +++++++ 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/22-target-side.md b/docs/22-target-side.md index 3ffce0792..e85ffe197 100644 --- a/docs/22-target-side.md +++ b/docs/22-target-side.md @@ -1011,7 +1011,9 @@ cxxflags = ["-D_GNU_SOURCE"] **A layer names the library, not the triple's env segment.** They coincide for `musl` and diverge for `gnu`: on Linux that segment asks for glibc, and on Windows it names the MinGW flavour of the toolchain, whose C runtime is the same -UCRT the MSVC flavour links. The spelling is `c-abi = "glibc"`, never +UCRT the MSVC flavour links. Both Windows payloads answer `ucrt` (the MSVC one +from 2026.11.10.2), so a package that needs the Win32 C runtime states +`requires = ["mcpp:c-abi=ucrt"]` once. The spelling is `c-abi = "glibc"`, never `c-abi = "gnu"`; the request, as opposed to the answer, is `env = "gnu"` — a different question (`docs/specs/target-side.md` §3.4). diff --git a/docs/specs/target-side.md b/docs/specs/target-side.md index 7ec9e20ae..94a5b6ef8 100644 --- a/docs/specs/target-side.md +++ b/docs/specs/target-side.md @@ -4,7 +4,7 @@ |---|---| | 规范编号 | SPEC-002 | | 标题 | 目标侧模型与能力声明(`mcpp:` 保留命名空间) | -| 状态 | 评审中 v1.6 | +| 状态 | 评审中 v1.7 | | 最后修改 | 2026-11-10 | | 对应实现 | mcpp >= 2026.8.24.2;§2.2 的对象形式与 §7 mcpp >= 2026.10.26.1 | | 相关设计文档 | `.agents/docs/2026-08-24-target-side-design.md`、`.agents/docs/2026-10-23-target-base-and-execution-host-design.md`、`.agents/docs/2026-10-26-control-contract-runtime-and-ide-ecosystem-design.md` §6 | @@ -186,6 +186,11 @@ mcpp:<层名>[=<实现名>] - 段存在且与解析出的 `c-abi` 不同,且后者来自图 ⇒ 引擎**必须**报出该不一致, 并**必须**给出不含该段的目标拼写;**禁止**据此使构建失败。 +段命名的是 C 库或工具集时,请求按其 C 库比较:`gnu` 在 Windows 上请求 `ucrt`,在其他系统上请求 +`glibc`;`msvc` 请求 `ucrt`。编译器载荷供给 `c-abi` 时,该层的实现名同样是 C 库的名字 +(`x86_64-windows-msvc` 与 `x86_64-windows-gnu` 的载荷均回答 `ucrt`),因此 `requires = ["mcpp:c-abi=ucrt"]` +被 Windows 上每一条带 Win32 C 运行时的路线满足(mcpp >= 2026.11.10.2)。 + 拒绝曾被实现并被实测否掉:它打破了每一个把宿主目标拼作 `x86_64-linux-gnu` 的工程与 CI 配置 —— 而那正是 `mcpp toolchain list` 打印的拼写。 判据是该请求**不改变任何东西**:图两种写法下都供给同一个 C 库, @@ -384,4 +389,5 @@ hosted 与否是 C 环境的一个声明:提供 `hosted-standard-library` 的 sy | v1.4 | 2026-11-03 | 随 mcpp 2026.11.3.1:§2.2 选择器引用层的 `requires` 在层解析之后检查(此前未检查即被丢弃)。 | | v1.5 | 2026-11-09 | 随 mcpp 2026.11.9.1:§3.4 身份随 C 库;新增 §3.6 能力的缺省提供者、§3.7 C 环境的声明(mcpp#911 G3、G7)。 | | v1.6 | 2026-11-10 | 随 mcpp 2026.11.10.1:新增 §2.5 基座包(按普通包读取:`provides` 回答层,`[build]` 陈述层,包根即 sysroot;新键 `compiler_runtime_dir`)与 §3.8 层供给者的需求不成环(`layer-cycle`)。 | +| v1.7 | 2026-11-10 | 随 mcpp 2026.11.10.2:§3.4 写明段与 C 库名的对应,MSVC 载荷的 `c-abi` 回答 `ucrt`。 | | v1.2 | 2026-10-23 | 随 mcpp 2026.10.24.1:§1.3 `prebuilt` 放宽为被点名、按内容识别的预制目录;§2.4 改为由测量回答、`provides` 声明或核对,标为已实现;规则一增加基座是一个供给者与 c-abi 独占律;规则二增加基座上的编译器运行库与可测量的下限;规则三增加可叠加层;新增 §6 目标侧执行(组合、运行器契约、物理边界)。 | diff --git a/docs/zh/22-target-side.md b/docs/zh/22-target-side.md index 2396726d4..302f6d14a 100644 --- a/docs/zh/22-target-side.md +++ b/docs/zh/22-target-side.md @@ -847,7 +847,9 @@ cxxflags = ["-D_GNU_SOURCE"] **层名指的是库,不是三元组的 env 段。** 二者在 `musl` 上重合,在 `gnu` 上 分叉:在 Linux 上该段请求的是 glibc,在 Windows 上它命名的是工具链的 -MinGW 形态,而后者的 C 运行时与 MSVC 形态链接的是同一个 UCRT。写法是 +MinGW 形态,而后者的 C 运行时与 MSVC 形态链接的是同一个 UCRT。两种 Windows 载荷都回答 +`ucrt`(MSVC 载荷自 2026.11.10.2 起),因此需要 Win32 C 运行时的包写一次 +`requires = ["mcpp:c-abi=ucrt"]` 即可。写法是 `c-abi = "glibc"`,而非 `c-abi = "gnu"`;与答案相对的那个「请求」是 `env = "gnu"`——这是另一个问题(`docs/specs/target-side.md` §3.4)。 diff --git a/modules/manifest/src/targetside_model.cppm b/modules/manifest/src/targetside_model.cppm index 24e12574c..21c2d2f32 100644 --- a/modules/manifest/src/targetside_model.cppm +++ b/modules/manifest/src/targetside_model.cppm @@ -681,6 +681,9 @@ struct Inputs { // compared through `c_abi_request_satisfied` rather than by equality. inline std::string payload_libc_name(std::string_view os, std::string_view env) { if (env == "gnu") return os == "windows" ? "ucrt" : "glibc"; + // `-msvc` names the toolset, as `-gnu` does on Windows: the C library of + // both is the Universal CRT, the name a base package states for it. + if (env == "msvc" && os == "windows") return "ucrt"; if (!env.empty()) return std::string(env); if (os == "macos") return "libSystem"; if (os == "windows") return "ucrt"; @@ -694,6 +697,7 @@ inline bool c_abi_request_satisfied(std::string_view requested, std::string_view resolved) { if (requested == resolved) return true; if (requested == "gnu") return resolved == "glibc" || resolved == "ucrt"; + if (requested == "msvc") return resolved == "ucrt"; if (requested == "glibc") return resolved == "gnu"; return false; } diff --git a/tests/unit/test_targetside.cpp b/tests/unit/test_targetside.cpp index 2289d5985..85fb93229 100644 --- a/tests/unit/test_targetside.cpp +++ b/tests/unit/test_targetside.cpp @@ -400,6 +400,12 @@ UTest the_payload_c_library_is_named_for_its_platform{"TargetSideResolve/ThePayl expect(eq(ts::resolve(winGnu).cAbi.interfaceName, "ucrt")) << "on Windows `-gnu` names the MinGW toolchain flavour, not glibc"; + auto winMsvc = payload_linux(); + winMsvc.targetOs = "windows"; + winMsvc.targetEnv = "msvc"; + expect(eq(ts::resolve(winMsvc).cAbi.interfaceName, "ucrt")) + << "on Windows `-msvc` names the toolset; its C library is the Universal CRT, as `-gnu`'s is"; + auto musl = payload_linux(); musl.targetEnv = "musl"; expect(eq(ts::resolve(musl).cAbi.interfaceName, "musl")) @@ -414,6 +420,7 @@ UTest the_env_request_is_satisfied_by_the_library_it_names{"TargetSideResolve/Th expect(bool(ts::c_abi_request_satisfied("gnu", "ucrt"))); expect(bool(ts::c_abi_request_satisfied("musl", "musl"))); expect(bool(ts::c_abi_request_satisfied("glibc", "gnu"))); + expect(bool(ts::c_abi_request_satisfied("msvc", "ucrt"))); expect(!ts::c_abi_request_satisfied("gnu", "musl")); expect(!ts::c_abi_request_satisfied("musl", "glibc")); }}; From 90e6365f6617e0fc6ddb5d4f8be09ffb47661d32 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Tue, 10 Nov 2026 23:32:27 +0900 Subject: [PATCH 02/13] 2026.11.10.2: FreeBSD's musl identity over openkal-platform 0.26.0 - The rows x86_64-freebsd-musl and aarch64-freebsd-musl are preview rows of the openkal provider (openkal-platform 0.26.0's hosted part: openkal-musl 0.29.2 over openkal-freebsd 0.1.0 standalone). A request of -freebsd with no platform selected for it takes that identity; a selected platform keeps the system ABI (e2e 1059). e2e 1073. - The openkal targets' platform is openkal-platform 0.26.0 (e2e 1025, the target-rows snapshot). - docs 21, 35, 50 (en, zh), SPEC targets-and-providers and platforms; CHANGELOG. --- CHANGELOG.md | 29 +++++++++++++++ docs/21-the-target-triple.md | 5 +-- docs/35-platforms.md | 2 +- docs/50-machine-output.md | 2 +- docs/specs/platforms.md | 2 +- docs/specs/targets-and-providers.md | 2 +- docs/zh/21-the-target-triple.md | 5 +-- docs/zh/35-platforms.md | 2 +- docs/zh/50-machine-output.md | 2 +- mcpp.toml | 2 +- modules/toolchain-model/data/builtin.toml | 14 ++++---- modules/versioning/src/version.cppm | 2 +- ...025_the_default_platform_is_one_release.sh | 12 +++---- ...ebsd_musl_identity_is_served_by_openkal.sh | 35 +++++++++++++++++++ tests/fixtures/target-rows.snapshot | 30 ++++++++-------- 15 files changed, 106 insertions(+), 40 deletions(-) create mode 100755 tests/e2e/1073_the_freebsd_musl_identity_is_served_by_openkal.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index b5907c80f..ba035f52c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,35 @@ > Each `## []` section is that release's notes. Entries are written in English > from 2026.9.28.3 on; earlier entries remain as written. +## [2026.11.10.2] - 2026-11-10 + +### Added + +- FreeBSD's musl identity is served: `x86_64-freebsd-musl` and + `aarch64-freebsd-musl` are preview rows of the openkal provider, through + openkal-platform 0.26.0's hosted part — openkal-musl 0.29.2 over + openkal-freebsd 0.1.0 in its standalone arrangement, with + openkal-llvm-runtime 0.20.1 above it, as one static program with no C library + of the system beneath. A request of `-freebsd` with no platform selected + for it takes this identity, as `aarch64-macos` takes the musl identity on a + host that is not a Mac; a project that selects a platform for `-freebsd` + keeps the system's own ABI. + +### Changed + +- The openkal targets' platform is openkal-platform 0.26.0 (from 0.25.0): its + version group is openkal-image 0.6.1, whose runner binds only the interfaces + its implementation provides and is built for FreeBSD as well, openkal-musl + 0.29.2, openkal-llvm-runtime 0.20.1 and openkal-freebsd 0.1.0. + +### Fixed + +- The MSVC payload's C library is `ucrt`, as the MinGW-w64 payload's is: the + triple's env segment names the toolset on Windows, `msvc` and `gnu` alike. + It was answered as `msvc`, so `requires = ["mcpp:c-abi=ucrt"]` (a Win32 + backend's statement of its C runtime) refused the MSVC route while the GNU + routes satisfied it. SPEC-002 v1.7 states the names. + ## [2026.11.10.1] - 2026-11-10 ### Added diff --git a/docs/21-the-target-triple.md b/docs/21-the-target-triple.md index ea73cd67f..7320bfaef 100644 --- a/docs/21-the-target-triple.md +++ b/docs/21-the-target-triple.md @@ -533,7 +533,7 @@ other's rows. | `aarch64-macos-musl` | preview | `llvm@23.1.3` | graph | graph | graph | graph | | `x86_64-macos-musl` | preview | `llvm@23.1.3` | graph | graph | graph | graph | | `x86_64-freebsd`, `aarch64-freebsd` | preview | — | platform | platform | platform | platform | -| `x86_64-freebsd-musl`, `aarch64-freebsd-musl` | planned | — | planned | planned | planned | planned | +| `x86_64-freebsd-musl`, `aarch64-freebsd-musl` | preview | `llvm@23.1.3` | graph | graph | graph | graph | | `riscv64-none-elf` | verified | `llvm@23.1.3` | payload | payload | payload | payload | | `riscv32-none-elf` | verified | `llvm@23.1.3` | payload | payload | payload | payload | | `aarch64-none-elf` | preview | `llvm@23.1.3` | payload | payload | payload | payload | @@ -573,7 +573,8 @@ vocabulary, nothing wired yet. | `*-linux-gnu` | Linux, same arch only | additionally needs the host-native `xim:glibc` / `xim:linux-headers` | | `x86_64-windows-gnu` | Linux and Windows by the gcc payload; every host by the MinGW-w64 base package | one identity, host-split at the distribution layer; the `mingw-llvm` provider serves it with clang and `xim:mingw-w64-sysroot` (llvm-mingw's target side: MinGW-w64 on UCRT, libc++, compiler-rt) where no gcc payload exists | | `aarch64-windows-gnu` | every host | the MinGW-w64 base package alone; no gcc payload targets it | -| `*-freebsd` | every host, through a platform | the rows are built-in; a platform names each identity's FreeBSD base package (`xim:x86_64-freebsd-sysroot`, `xim:aarch64-freebsd-sysroot`) and is selected with `[target.] platform`; without one the request is refused naming that line | +| `*-freebsd` | every host, through a platform | the rows are built-in; a platform names each identity's FreeBSD base package (`xim:x86_64-freebsd-sysroot`, `xim:aarch64-freebsd-sysroot`) and is selected with `[target.] platform` | +| `*-freebsd-musl` | every host, through the graph | openkal-platform's hosted part (0.26.0): openkal-musl over openkal-freebsd standalone, one static program; a request of `-freebsd` with no platform selected for it takes this identity (2026.11.10.2+), as `aarch64-macos` takes the musl identity on a host that is not a Mac | | `x86_64-windows-msvc` | Windows | MSVC is located on the machine | | `x86_64-windows-musl` | Windows by payload; anywhere by graph | no gcc emits PE+musl, and LLVM cannot spell the triple | | `aarch64-macos` | macOS | the SDK is the machine's | diff --git a/docs/35-platforms.md b/docs/35-platforms.md index cdd96a0c4..f0a36a644 100644 --- a/docs/35-platforms.md +++ b/docs/35-platforms.md @@ -203,7 +203,7 @@ manifest, ```toml [target.'cfg(os = "openkal")'] -platform = "openkal-platform@0.25.0" # a release, or a series: "openkal-platform@^0.25" +platform = "openkal-platform@0.26.0" # a release, or a series: "openkal-platform@^0.26" ``` and a build that fails while the default is in use and the synced index holds a diff --git a/docs/50-machine-output.md b/docs/50-machine-output.md index 248532f7a..95f514930 100644 --- a/docs/50-machine-output.md +++ b/docs/50-machine-output.md @@ -552,7 +552,7 @@ installation, which is located on the machine rather than installed by mcpp. A target row is `{target, note, toolchain, pin, status, default}`, and `status` is one of `installed` / `available` / `via dependency graph` / `planned`. A target row also carries `platform` (2026.10.27.1+): the platform package the -target table selects for it (`mcpplibs.openkal-platform@0.25.0` from 2026.11.10.1, `@0.24.4` from 2026.11.8.1, `@0.24.3` in 2026.11.7.2; the series `^0.24` in 2026.11.7.1), or `null`. +target table selects for it (`mcpplibs.openkal-platform@0.26.0` from 2026.11.10.2, `@0.25.0` in 2026.11.10.1, `@0.24.4` from 2026.11.8.1, `@0.24.3` in 2026.11.7.2; the series `^0.24` in 2026.11.7.1), or `null`. **`toolchain` and `pin` are not the same field twice.** `toolchain` is what the row is associated with — the installed payload on an installed row, the diff --git a/docs/specs/platforms.md b/docs/specs/platforms.md index 25c5dff5f..58db714ad 100644 --- a/docs/specs/platforms.md +++ b/docs/specs/platforms.md @@ -405,7 +405,7 @@ run_under = ["qemu-aarch64"] ## 14. 内置平台与目标表 宿主目标(Linux、macOS、Windows、Android、iOS、Emscripten)的约定留在引擎中,无平台包。目标表有平台列: -`x86_64-openkal`、`aarch64-openkal` 的值为一个确切的平台版本,即当前引擎验证过的版本(mcpp 2026.11.10.1 为 `mcpplibs.openkal-platform@0.25.0`), +`x86_64-openkal`、`aarch64-openkal` 的值为一个确切的平台版本,即当前引擎验证过的版本(mcpp 2026.11.10.2 为 `mcpplibs.openkal-platform@0.26.0`), 也是这两个目标的内置支持;选择来源报告为 `built-in`。项目可以以 `[target.] platform` 选择另一个版本或系列。 锁中记录的版本不满足内置版本时不被采用,报告写出采用的版本与锁中记录的版本。使用内置版本的构建失败、且已同步的索引中 有更新版本时,构建以一条 `tip` 写出两个版本与选择它的写法(mcpp >= 2026.11.7.2;2026.11.7.1 的值为系列 `^0.24`)。**已实现** diff --git a/docs/specs/targets-and-providers.md b/docs/specs/targets-and-providers.md index 6af5e6536..015d7612a 100644 --- a/docs/specs/targets-and-providers.md +++ b/docs/specs/targets-and-providers.md @@ -54,7 +54,7 @@ - 内置行的 os 与 env 是解析器接受的词,与平台定义的行相同(v1.1)。 - 主流系统的两种身份都是内置数据(v1.1):系统自身 ABI 的行(`x86_64-freebsd`、`aarch64-freebsd`)没有内置提供者,由平台 提供;未选平台时,请求被拒绝并指名 `[target.<身份>] platform`。openkal 的 hosted 行(`x86_64-freebsd-musl`、 - `aarch64-freebsd-musl`)在其实现发布前为 planned。 + `aarch64-freebsd-musl`)由 openkal 提供者经 openkal-platform 0.26.0 服务(openkal-freebsd 0.1.0 发布后,mcpp >= 2026.11.10.2)。 - 32 位 hosted 行(`i686-linux-musl`、`i686-linux-gnu`、`i686-openkal`)为 planned(v1.1):请求按 planned 拒绝,而非按 未知目标;显式的 `[target.<身份>] toolchain` 可提前启用。 diff --git a/docs/zh/21-the-target-triple.md b/docs/zh/21-the-target-triple.md index 7cce739eb..541cd445f 100644 --- a/docs/zh/21-the-target-triple.md +++ b/docs/zh/21-the-target-triple.md @@ -492,7 +492,7 @@ docs/22。 | `aarch64-macos-musl` | preview | `llvm@23.1.3` | 图 | 图 | 图 | 图 | | `x86_64-macos-musl` | preview | `llvm@23.1.3` | 图 | 图 | 图 | 图 | | `x86_64-freebsd`、`aarch64-freebsd` | preview | — | 平台 | 平台 | 平台 | 平台 | -| `x86_64-freebsd-musl`、`aarch64-freebsd-musl` | planned | — | planned | planned | planned | planned | +| `x86_64-freebsd-musl`、`aarch64-freebsd-musl` | preview | `llvm@23.1.3` | graph | graph | graph | graph | | `riscv64-none-elf` | verified | `llvm@23.1.3` | 载荷 | 载荷 | 载荷 | 载荷 | | `riscv32-none-elf` | verified | `llvm@23.1.3` | 载荷 | 载荷 | 载荷 | 载荷 | | `aarch64-none-elf` | preview | `llvm@23.1.3` | 载荷 | 载荷 | 载荷 | 载荷 | @@ -530,7 +530,8 @@ system · `系统` 在机器上被找到,不是 mcpp 安装的 · `SDK` 平台 | `*-linux-gnu` | Linux,且仅同架构 | 还需要本机架构的 `xim:glibc` / `xim:linux-headers` | | `x86_64-windows-gnu` | Linux 与 Windows 经 gcc 载荷;每一台宿主经 MinGW-w64 基座包 | 一个身份,只在分发层按宿主拆分;没有 gcc 载荷之处,`mingw-llvm` 提供者以 clang 与 `xim:mingw-w64-sysroot`(llvm-mingw 的目标侧:UCRT 上的 MinGW-w64、libc++、compiler-rt)服务它 | | `aarch64-windows-gnu` | 每一台宿主 | 只由 MinGW-w64 基座包服务;没有 gcc 载荷以它为目标 | -| `*-freebsd` | 每一台宿主,经平台 | 行是内置的;平台为每个身份指名 FreeBSD 基座包(`xim:x86_64-freebsd-sysroot`、`xim:aarch64-freebsd-sysroot`),以 `[target.<行>] platform` 选择;未选平台时请求被拒绝并写出这一行 | +| `*-freebsd` | 每一台宿主,经平台 | 行是内置的;平台为每个身份指名 FreeBSD 基座包(`xim:x86_64-freebsd-sysroot`、`xim:aarch64-freebsd-sysroot`),以 `[target.<行>] platform` 选择 | +| `*-freebsd-musl` | 每一台宿主,经依赖图 | openkal-platform 的 hosted 部分(0.26.0):openkal-freebsd 的 standalone 形态之上的 openkal-musl,一个静态程序;未为 `-freebsd` 选平台时,该请求取这一身份(2026.11.10.2+),正如非 Mac 宿主上的 `aarch64-macos` 取 musl 身份 | | `x86_64-windows-msvc` | Windows | MSVC 是在机器上被找到的 | | `x86_64-windows-musl` | payload 只在 Windows 上;图则任意宿主 | 没有 gcc 能发出 PE + musl,且 LLVM 拼不出这个三元组 | | `aarch64-macos` | macOS | SDK 是那台机器自己的 | diff --git a/docs/zh/35-platforms.md b/docs/zh/35-platforms.md index a6fcc3138..2332478bb 100644 --- a/docs/zh/35-platforms.md +++ b/docs/zh/35-platforms.md @@ -168,7 +168,7 @@ error: openkal-musl is requested as '^0.27.0' by app, and the platform openkal-p ```toml [target.'cfg(os = "openkal")'] -platform = "openkal-platform@0.25.0" # 一个版本,或一个系列:"openkal-platform@^0.25" +platform = "openkal-platform@0.26.0" # 一个版本,或一个系列:"openkal-platform@^0.26" ``` 使用默认平台的构建失败、且已同步的索引中有更新版本时,最后输出一行 `tip:`,写出两个版本与上面这一行。 diff --git a/docs/zh/50-machine-output.md b/docs/zh/50-machine-output.md index d4ef213f7..d92b7a778 100644 --- a/docs/zh/50-machine-output.md +++ b/docs/zh/50-machine-output.md @@ -488,7 +488,7 @@ mcpp toolchain list --format json 的形状是 `{target, note, toolchain, pin, status, default}`,`status` 取 `installed` / `available` / `via dependency graph` / `planned` 之一。 目标行另有 `platform`(2026.10.27.1+):目标表为该目标选择的平台包 -(2026.11.10.1 起为 `mcpplibs.openkal-platform@0.25.0`,2026.11.8.1 起为 `@0.24.4`,2026.11.7.2 为 `@0.24.3`;2026.11.7.1 为系列 `^0.24`),或 `null`。 +(2026.11.10.2 起为 `mcpplibs.openkal-platform@0.26.0`,2026.11.10.1 为 `@0.25.0`,2026.11.8.1 起为 `@0.24.4`,2026.11.7.2 为 `@0.24.3`;2026.11.7.1 为系列 `^0.24`),或 `null`。 **`toolchain` 与 `pin` 不是把同一个字段写了两遍。** `toolchain` 表示这一行 关联到什么 —— 已装的行是装好的载荷,词表行是它自己的约定。`pin` 只承载目标 diff --git a/mcpp.toml b/mcpp.toml index e7a8f5d27..c56ce4699 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -1,6 +1,6 @@ [package] name = "mcpp" -version = "2026.11.10.1" +version = "2026.11.10.2" description = "Modern C++ build & package management tool" license = "Apache-2.0" authors = ["mcpp-community"] diff --git a/modules/toolchain-model/data/builtin.toml b/modules/toolchain-model/data/builtin.toml index 74078903d..0d9014a89 100644 --- a/modules/toolchain-model/data/builtin.toml +++ b/modules/toolchain-model/data/builtin.toml @@ -163,8 +163,8 @@ standard = false # system's own ABI -- libc, libc++ over libcxxrt -- is served by a platform that # states the system's sysroot; no built-in provider serves it, and a request is # refused naming that until a platform is selected. The musl identity is -# openkal-platform's hosted part over openkal-freebsd, planned until that -# implementation is released. 14.0 is the release the triple names: a program +# openkal-platform's hosted part over openkal-freebsd (openkal-platform 0.26.0: +# openkal-musl 0.29.2 over openkal-freebsd 0.1.0, standalone). 14.0 is the release the triple names: a program # built for it runs on every later 14.x and, through the kernel's # COMPAT_FREEBSD14, on 15. [[platform.define]] @@ -181,13 +181,13 @@ clang-triple = "aarch64-unknown-freebsd14.0" [[platform.define]] triple = "x86_64-freebsd-musl" -tier = "planned" +tier = "preview" standard = false clang-triple = "x86_64-unknown-freebsd14.0" [[platform.define]] triple = "aarch64-freebsd-musl" -tier = "planned" +tier = "preview" standard = false clang-triple = "aarch64-unknown-freebsd14.0" @@ -540,14 +540,14 @@ hosts = ["*"] toolchain = "llvm@23.1.3" pairs = ["llvm"] linkage = "static" -platform = "mcpplibs.openkal-platform@0.25.0" +platform = "mcpplibs.openkal-platform@0.26.0" [[platform.provider]] name = "openkal" -serves = ["x86_64-windows-musl", "*-linux-musl", "*-macos-musl"] +serves = ["x86_64-windows-musl", "*-linux-musl", "*-macos-musl", "*-freebsd-musl"] priority = 50 hosts = ["*"] toolchain = "llvm@23.1.3" pairs = ["llvm"] linkage = "static" -platform = "mcpplibs.openkal-platform@0.25.0" +platform = "mcpplibs.openkal-platform@0.26.0" diff --git a/modules/versioning/src/version.cppm b/modules/versioning/src/version.cppm index 32517eadf..b05648255 100644 --- a/modules/versioning/src/version.cppm +++ b/modules/versioning/src/version.cppm @@ -31,6 +31,6 @@ import std; export namespace mcpp { -inline constexpr std::string_view MCPP_VERSION = "2026.11.10.1"; +inline constexpr std::string_view MCPP_VERSION = "2026.11.10.2"; } // namespace mcpp diff --git a/tests/e2e/1025_the_default_platform_is_one_release.sh b/tests/e2e/1025_the_default_platform_is_one_release.sh index 1fba32ab9..ee23800ac 100755 --- a/tests/e2e/1025_the_default_platform_is_one_release.sh +++ b/tests/e2e/1025_the_default_platform_is_one_release.sh @@ -7,9 +7,9 @@ # # Criteria: # A. A project that states no platform builds `x86_64-openkal` over -# openkal-platform 0.25.0, from the target table, and mcpp.lock records it. +# openkal-platform 0.26.0, from the target table, and mcpp.lock records it. # B. A lock that records another release of it does not decide: the build -# says which it takes and which the lock recorded, and records 0.25.0. +# says which it takes and which the lock recorded, and records 0.26.0. # C. A platform the project states is taken as it is (a series here). set -e TMP=$(mktemp -d) @@ -30,20 +30,20 @@ PY # A "$MCPP" build --target x86_64-openkal > a.log 2>&1 || fail "A: the openkal build failed" a.log -grep -q 'Platform *openkal-platform 0.25.0' a.log || fail "A: the build does not use openkal-platform 0.25.0" a.log -[[ "$(locked)" == "0.25.0" ]] || fail "A: mcpp.lock does not record 0.25.0" mcpp.lock +grep -q 'Platform *openkal-platform 0.26.0' a.log || fail "A: the build does not use openkal-platform 0.26.0" a.log +[[ "$(locked)" == "0.26.0" ]] || fail "A: mcpp.lock does not record 0.26.0" mcpp.lock # B $PY - <<'PY' import re text = open("mcpp.lock").read() -text = re.sub(r'(\[package\."openkal-platform"\][^\[]*?version\s*=\s*")0\.25\.0(")', r'\g<1>0.24.3\2', text, count=1) +text = re.sub(r'(\[package\."openkal-platform"\][^\[]*?version\s*=\s*")0\.26\.0(")', r'\g<1>0.24.3\2', text, count=1) open("mcpp.lock", "w").write(text) PY [[ "$(locked)" == "0.24.3" ]] || fail "B: the fixture could not edit mcpp.lock" mcpp.lock "$MCPP" build --target x86_64-openkal > b.log 2>&1 || fail "B: the openkal build failed" b.log grep -q "default; mcpp.lock recorded v0.24.3" b.log || fail "B: the build does not say which release it takes over the lock's" b.log -[[ "$(locked)" == "0.25.0" ]] || fail "B: mcpp.lock was not rewritten to 0.25.0" mcpp.lock +[[ "$(locked)" == "0.26.0" ]] || fail "B: mcpp.lock was not rewritten to 0.26.0" mcpp.lock # C cat >> mcpp.toml <<'EOT' diff --git a/tests/e2e/1073_the_freebsd_musl_identity_is_served_by_openkal.sh b/tests/e2e/1073_the_freebsd_musl_identity_is_served_by_openkal.sh new file mode 100755 index 000000000..375d44460 --- /dev/null +++ b/tests/e2e/1073_the_freebsd_musl_identity_is_served_by_openkal.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# requires: llvm elf +# 1073 -- FreeBSD's musl identity is served by openkal (design 2026-11-10 E4, K8, +# K9; docs/21 'Build hosts and the targets they serve'). +# +# `x86_64-freebsd-musl` is openkal-platform's hosted part (0.26.0): openkal-musl +# over openkal-freebsd in its standalone arrangement, linked as one static +# program with no C library of the system beneath. A request of `x86_64-freebsd` +# with no platform selected for it takes that identity, as `aarch64-macos` +# takes the musl identity on a host that is not a Mac; a project that selects a +# platform for `x86_64-freebsd` keeps the system's own ABI (e2e 1059). +# +# Criteria: `--target x86_64-freebsd-musl` builds a static FreeBSD ELF over +# openkal-musl and openkal-freebsd; `--target x86_64-freebsd` with no platform +# selected builds the same identity and says so. +set -e +TMP=$(mktemp -d) +trap 'rm -rf "$TMP"' EXIT +fail() { echo "FAIL: $1"; shift; for f in "$@"; do echo "--- $f ---"; tail -30 "$f" 2>/dev/null; done; exit 1; } + +cd "$TMP" +"$MCPP" new app > /dev/null 2>&1 +cd app +"$MCPP" build --target x86_64-freebsd-musl > a.log 2>&1 || fail "A: x86_64-freebsd-musl did not build" a.log +grep -q 'openkal-musl@' a.log || fail "A: the C library is not openkal-musl" a.log +grep -q 'openkal-freebsd@' a.log || fail "A: the kernel layer is not openkal-freebsd" a.log +exe=$(find target/x86_64-freebsd-musl -path '*/bin/app' -type f | head -1) +[ -n "$exe" ] || fail "A: no program" a.log +info=$(file "$exe") +grep -q 'FreeBSD' <<<"$info" || fail "A: not a FreeBSD program: $info" +grep -q 'statically linked' <<<"$info" || fail "A: not static: $info" + +"$MCPP" build --target x86_64-freebsd > b.log 2>&1 || fail "B: x86_64-freebsd with no platform did not build" b.log +grep -q 'x86_64-freebsd-musl' b.log || fail "B: the request does not say it took the musl identity" b.log +echo "PASS: 1073 the FreeBSD musl identity is served by openkal" diff --git a/tests/fixtures/target-rows.snapshot b/tests/fixtures/target-rows.snapshot index 9113a8e45..78bc04f8e 100644 --- a/tests/fixtures/target-rows.snapshot +++ b/tests/fixtures/target-rows.snapshot @@ -113,7 +113,7 @@ row aarch64-windows-gnu descriptor-keys windows sysroot xim:mingw-w64-sysroot@20261104-2 row x86_64-windows-musl - table tier=preview note=PE pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.25.0 + table tier=preview note=PE pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.26.0 str x86_64-windows-musl llvm x86_64-w64-windows-gnu llvm@15.0 x86_64-w64-windows-gnu @@ -170,7 +170,7 @@ row aarch64-macos descriptor-keys macosx sysroot row aarch64-macos-musl - table tier=preview note= pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.25.0 + table tier=preview note= pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.26.0 str aarch64-macos-musl llvm arm64-apple-macos14.0 llvm@15.0 arm64-apple-macos15.0 @@ -208,7 +208,7 @@ row riscv64-linux-musl descriptor-keys linux sysroot row i686-linux-musl - table tier=planned note= pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.25.0 + table tier=planned note= pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.26.0 str i686-linux-musl llvm i686-unknown-linux-musl llvm@15.0 i686-unknown-linux-musl @@ -246,7 +246,7 @@ row i686-linux-gnu descriptor-keys linux sysroot row i686-openkal - table tier=planned note=ok pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.25.0 + table tier=planned note=ok pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.26.0 str i686-openkal llvm i686-unknown-none-elf llvm@15.0 i686-unknown-none-elf @@ -284,7 +284,7 @@ row x86_64-macos descriptor-keys macosx sysroot row x86_64-macos-musl - table tier=preview note= pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.25.0 + table tier=preview note= pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.26.0 str x86_64-macos-musl llvm x86_64-apple-macos14.0 llvm@15.0 x86_64-apple-macos15.0 @@ -341,7 +341,7 @@ row aarch64-freebsd descriptor-keys freebsd sysroot row x86_64-freebsd-musl - table tier=planned note= pin= sysroot= static=0 platform= + table tier=preview note= pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.26.0 str x86_64-freebsd-musl llvm x86_64-unknown-freebsd14.0 llvm@15.0 x86_64-unknown-freebsd14.0 @@ -349,7 +349,7 @@ row x86_64-freebsd-musl family pe/macho/wasm 000 apple/ios/sim/android 0000 - freestanding/openkal/own-sysroot/capability 0000 + freestanding/openkal/own-sysroot/capability 0001 musl/msvc/windows-gnu/x86_32 1000 msvc-arch x64 nasm - @@ -360,7 +360,7 @@ row x86_64-freebsd-musl descriptor-keys freebsd sysroot row aarch64-freebsd-musl - table tier=planned note= pin= sysroot= static=0 platform= + table tier=preview note= pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.26.0 str aarch64-freebsd-musl llvm aarch64-unknown-freebsd14.0 llvm@15.0 aarch64-unknown-freebsd14.0 @@ -368,7 +368,7 @@ row aarch64-freebsd-musl family pe/macho/wasm 000 apple/ios/sim/android 0000 - freestanding/openkal/own-sysroot/capability 0000 + freestanding/openkal/own-sysroot/capability 0001 musl/msvc/windows-gnu/x86_32 1000 msvc-arch arm64 nasm - @@ -817,7 +817,7 @@ row wasm32-emscripten descriptor-keys emscripten linux sysroot row x86_64-openkal - table tier=verified note=ok pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.25.0 + table tier=verified note=ok pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.26.0 str x86_64-openkal llvm x86_64-unknown-none-elf llvm@15.0 x86_64-unknown-none-elf @@ -836,7 +836,7 @@ row x86_64-openkal descriptor-keys openkal linux sysroot row aarch64-openkal - table tier=verified note=ok pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.25.0 + table tier=verified note=ok pin=llvm@23.1.3 sysroot= static=1 platform=mcpplibs.openkal-platform@0.26.0 str aarch64-openkal llvm aarch64-unknown-none-elf llvm@15.0 aarch64-unknown-none-elf @@ -956,9 +956,9 @@ request i686-none-elf on windows-x86_64 -> i686-none-elf bare-metal fallback=0 | i686-none-elf/bare-metal/100 request x86_64-freebsd parsed x86_64-freebsd envExplicit=0 - on linux-x86_64 -> x86_64-freebsd - fallback=0 | x86_64-freebsd/-/0 - on macos-aarch64 -> x86_64-freebsd - fallback=0 | x86_64-freebsd/-/0 - on windows-x86_64 -> x86_64-freebsd - fallback=0 | x86_64-freebsd/-/0 + on linux-x86_64 -> x86_64-freebsd-musl openkal fallback=0 | x86_64-freebsd-musl/openkal/50 x86_64-freebsd/-/0 + on macos-aarch64 -> x86_64-freebsd-musl openkal fallback=0 | x86_64-freebsd-musl/openkal/50 x86_64-freebsd/-/0 + on windows-x86_64 -> x86_64-freebsd-musl openkal fallback=0 | x86_64-freebsd-musl/openkal/50 x86_64-freebsd/-/0 request x86_64-linux-gnux32 unparseable did-you-mean x86_64-linux-mus x86_64-linux-musl @@ -971,7 +971,7 @@ set linux-musl -> x86_64-linux-musl aarch64-linux-musl | set windows -> x86_64-windows-gnu aarch64-windows-gnu | set windows-msvc -> x86_64-windows-msvc | set macos -> aarch64-macos | -set openkal -> x86_64-openkal aarch64-openkal | mcpplibs.openkal-platform@0.25.0 +set openkal -> x86_64-openkal aarch64-openkal | mcpplibs.openkal-platform@0.26.0 set none-elf -> riscv64-none-elf riscv32-none-elf aarch64-none-elf x86_64-none-elf i686-none-elf | set none-eabihf -> thumbv7em-none-eabihf thumbv8m.main-none-eabihf armv7a-none-eabihf | set android -> aarch64-linux-android x86_64-linux-android | From b0e084ac870b9780c60fdcd2ffb1e42290c47d91 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Tue, 10 Nov 2026 23:33:07 +0900 Subject: [PATCH 03/13] Design notes: K9 and the I1 correction in the implementation record --- .agents/docs/2026-11-10-cross-platform-ecosystem-design.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.agents/docs/2026-11-10-cross-platform-ecosystem-design.md b/.agents/docs/2026-11-10-cross-platform-ecosystem-design.md index eb2ce8d21..7c33a08a2 100644 --- a/.agents/docs/2026-11-10-cross-platform-ecosystem-design.md +++ b/.agents/docs/2026-11-10-cross-platform-ecosystem-design.md @@ -6,7 +6,7 @@ status: active # 生态方案:跨平台通用基础设施(mcpp + openkal + xim),以一个 C89 工程为验证 **日期:** 2026-11-10 -**状态:** 第四版,mcpp 部分已在 2026.11.10.1 实施。Q1–Q6 已定稿(第 11.1 节);O1–O4 已按推荐实施,实施中的调整见第 11.2 节;第 12 节为两项 +**状态:** 第四版,mcpp 部分已在 2026.11.10.1 实施,K9 与 I1 的补正在 2026.11.10.2。Q1–Q6 已定稿(第 11.1 节);O1–O4 已按推荐实施,实施中的调整见第 11.2 节;第 12 节为两项 风险的说明,第 13 节为多视角深度自审;第 15 节为实施记录,第 16 节为测试体系向 mtest 的迁移 **范围:** mcpp(引擎与内置数据);openkal 家族(openkal 规范、openkal-linux/macos/windows、openkal-musl、 openkal-llvm-runtime、openkal-image、openkal-platform、openkal-conformance,新增 openkal-freebsd、openkal-posix); @@ -592,6 +592,8 @@ B 路线在 Windows 上就是正确的默认。 | I1 | compat.glfw 的 Windows 行要求 `mcpp:c-abi=ucrt` | gnu 行构建、windows-musl 行在解析期拒绝(实测) | | CI 中暴露并修复 | 提供者的基座在依赖图载入前被记住(改为图载入后才保留);没有 cfg 的 Windows llvm 载荷编译时不陈述配对的 sysroot;同一 home 的两个进程并发安装同一个包(安装次序锁 `registry/.install.lock`) | target-matrix、openkal 交叉构建、各宿主 e2e | | 实施中发现并修复 | 工具链为另一目标构建的 C++ 归档(其父目录的三元组与目标的架构或系统不同)不链接,并给出降级诊断;ok 映像的启动器依赖 mcpplibs.os 0.4.4(openkal 0.24 与 0.25 两族均可);交叉 gcc 自身的 Windows 头文件属于工具链(`mingw` 提供者下资源脚本的 `"winres.h"`);资源脚本中各处都找不到、也无构建动作写出的带引号 include 不进入构建图,由脚本的预处理与资源编译器处理 | 单元测试 `Distribution/ForeignArchivesAreNotLinked`;mingw 交叉打包;e2e 1058、1072(验证工程的 Windows 行暴露) | +| K9(mcpp 2026.11.10.2) | `-freebsd-musl` 两行由 openkal 提供者经 openkal-platform 0.26.0 的 hosted 部分服务(openkal-freebsd standalone 之上的 openkal-musl 0.29.2);未为 `-freebsd` 选平台时取该身份,选了平台则保留系统 ABI;openkal-run 0.6.1 在 FreeBSD 上以 openkal-freebsd 为缺省实现,okrun 由两条路线构建;平台的运行器主机加入 FreeBSD | e2e 1073、1059;openkal-platform CI 的 freebsd 作业(FreeBSD 虚拟机中运行程序,并以 FreeBSD 的 okrun 运行 ok 映像) | +| I1 的补正(mcpp 2026.11.10.2) | MSVC 载荷的 `c-abi` 回答 `ucrt`(此前为工具集名 `msvc`),`compat.glfw` 的 `requires = ["mcpp:c-abi=ucrt"]` 在 MSVC 行上成立;SPEC-002 v1.7 写明段与 C 库名的对应 | 单元测试 `TargetSideResolve`;mcpp-index#748 的 Windows 作业 | openkal 家族(K5、K6,openkal 0.25.0)、openkal-freebsd 0.1.0(hosted 与 standalone 两种形态,x86_64 与 arm64)、 openkal-musl 0.29.1 与 openkal-llvm-runtime 0.20.1(FreeBSD 的 standalone C 与 C++ 运行时)以及 mcpplibs/os 的实施记录 From bec0fac376600c33740ceacd6093c295264691bb Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Wed, 11 Nov 2026 00:08:56 +0900 Subject: [PATCH 04/13] cfg barewords are the rows' systems, and a row states its family - A bareword other than `unix` is `os = ""` for any word without a dash, so `[target.freebsd]`, `cfg(freebsd)` and the system of a row a platform defines select as `linux` does. The vocabulary the diagnostic names is the rows' systems; a word naming none is reported as before. - A row states its family (`family`, `unix` or `windows`); FreeBSD's rows are of the `unix` family, so `cfg(unix)` holds on them. - docs/22, docs/35; unit tests CfgBarewords; the target-rows snapshot. --- docs/22-target-side.md | 16 ++++--- docs/35-platforms.md | 2 +- docs/zh/22-target-side.md | 11 +++-- docs/zh/35-platforms.md | 2 +- modules/manifest/src/cfg_selector.cppm | 20 ++++++--- modules/toolchain-model/build.mcpp | 11 +++-- modules/toolchain-model/data/builtin.toml | 6 +++ modules/toolchain-model/src/triple.cppm | 4 ++ src/build/prepare_inputs.cppm | 41 ++++++++++++------ tests/fixtures/target-rows.snapshot | 8 ++-- tests/unit/test_cfg_barewords.cpp | 52 +++++++++++++++++++++++ 11 files changed, 134 insertions(+), 39 deletions(-) create mode 100644 tests/unit/test_cfg_barewords.cpp diff --git a/docs/22-target-side.md b/docs/22-target-side.md index e85ffe197..ae6f7e205 100644 --- a/docs/22-target-side.md +++ b/docs/22-target-side.md @@ -1093,15 +1093,21 @@ openblas = "0.3.33" ldflags = ["-Llib", "-llibopenblas"] # cfg(...) for compound predicates (grammar: all/any/not over os/arch/family/env, -# plus the bare aliases windows/unix/linux/macos). +# plus barewords: `unix` and the name of a system). [target.'cfg(all(linux, not(arch = "aarch64")))'.build] cxxflags = ["-march=x86-64-v2"] ``` -`[target.windows]` is exactly equivalent to `[target.'cfg(windows)']` — the bare -aliases `windows` / `linux` / `macos` / `unix` are never valid target triples, so -there is no ambiguity. Use the bare form for a single OS/family; use `cfg(...)` -for arch/env conditions and combinators. +`[target.windows]` is exactly equivalent to `[target.'cfg(windows)']`. A bareword +is data rather than a list: `unix` is `family = "unix"`, and any other word without a +dash is `os = ""` (`linux`, `macos`, `windows`, `freebsd`, or the system of a +row a platform defines). A row states its family (`family` in the row table), so +FreeBSD is of the `unix` family. A target triple always contains a dash, so a +bareword is never a triple. A word that names no row's system is reported, as an +unknown key is. Use the bare form for a single OS/family; use `cfg(...)` for arch/env +conditions and combinators. mcpp before 2026.11.10.2 reads only `linux`, `macos`, +`windows` and `unix` as barewords; a package read by such a release writes +`cfg(os = "")` for any other system. - **Keys**: `dependencies` / `dev-dependencies` / `build-dependencies` / `feature-deps.` (mcpp 2026.8.6.2+ — see [30 — build.mcpp](30-build-mcpp.md); the feature is diff --git a/docs/35-platforms.md b/docs/35-platforms.md index f0a36a644..131b4ca17 100644 --- a/docs/35-platforms.md +++ b/docs/35-platforms.md @@ -311,7 +311,7 @@ hosted = true # the C environment has `main` With the platform selected (`[target.x86_64-haiku] platform = {...}` or `--platform`), `--target x86_64-haiku` builds into `target/x86_64-haiku/`, -`cfg(os = "haiku")` holds, and a program whose system is not this machine's +`cfg(os = "haiku")` holds (and `cfg(haiku)`, `cfg(unix)` by the row's `family`, 2026.11.10.2+), and a program whose system is not this machine's is built, not run, until a runner states how it runs (docs/41). The row's machine description is the platform's: a target whose machine differs from a built-in row is another row. `[platform]` and `[platform.hosted]` remain the two diff --git a/docs/zh/22-target-side.md b/docs/zh/22-target-side.md index 302f6d14a..0b70acfd9 100644 --- a/docs/zh/22-target-side.md +++ b/docs/zh/22-target-side.md @@ -920,14 +920,17 @@ openblas = "0.3.33" ldflags = ["-Llib", "-llibopenblas"] # cfg(...) for compound predicates (grammar: all/any/not over os/arch/family/env, -# plus the bare aliases windows/unix/linux/macos). +# plus barewords: `unix` and the name of a system). [target.'cfg(all(linux, not(arch = "aarch64")))'.build] cxxflags = ["-march=x86-64-v2"] ``` -`[target.windows]` 与 `[target.'cfg(windows)']` 完全等价——裸别名 -`windows` / `linux` / `macos` / `unix` 都不是合法的目标三元组,因此不存在 -歧义。单个 OS/族用裸形式,arch/env 条件与组合子用 `cfg(...)`。 +`[target.windows]` 与 `[target.'cfg(windows)']` 完全等价。裸词由数据决定而非列表:`unix` 即 +`family = "unix"`,其余不含短横线的词即 `os = "<词>"`(`linux`、`macos`、`windows`、`freebsd`, +或平台所定义行的系统)。行陈述其族(行表中的 `family`),因此 FreeBSD 属于 `unix` 族。目标三元组 +必含短横线,故裸词不会是三元组。不对应任何行之系统的词与未知键一样会被报告。单个 OS/族用裸形式, +arch/env 条件与组合子用 `cfg(...)`。2026.11.10.2 之前的 mcpp 仅将 `linux`、`macos`、`windows` +与 `unix` 读作裸词;需要被这些版本读取的包对其他系统写 `cfg(os = "<系统>")`。 - **可用键**:`dependencies` / `dev-dependencies` / `build-dependencies` / `feature-deps.`(mcpp 2026.8.6.2+——见 diff --git a/docs/zh/35-platforms.md b/docs/zh/35-platforms.md index 2332478bb..19e435388 100644 --- a/docs/zh/35-platforms.md +++ b/docs/zh/35-platforms.md @@ -257,7 +257,7 @@ hosted = true # C 环境有 `main` ``` 选中该平台(`[target.x86_64-haiku] platform = {...}` 或 `--platform`)后,`--target x86_64-haiku` 构建到 -`target/x86_64-haiku/`,`cfg(os = "haiku")` 成立;程序的系统不是本机时,在运行器陈述运行方式之前为「已构建、 +`target/x86_64-haiku/`,`cfg(os = "haiku")` 成立(2026.11.10.2 起 `cfg(haiku)` 亦成立,`cfg(unix)` 由行的 `family` 决定);程序的系统不是本机时,在运行器陈述运行方式之前为「已构建、 未运行」(docs/41)。行的机器描述属于平台:机器与内置行不同的目标是另一行。`[platform]` 与 `[platform.hosted]` 仍是 提供者的两种简写。 diff --git a/modules/manifest/src/cfg_selector.cppm b/modules/manifest/src/cfg_selector.cppm index cd210192b..8ef2cdd31 100644 --- a/modules/manifest/src/cfg_selector.cppm +++ b/modules/manifest/src/cfg_selector.cppm @@ -15,7 +15,7 @@ // Specificity is the set of target-triple components a selector fixes: // // a bare triple (`x86_64-unknown-linux-gnu`) every component; above any cfg -// `os = "…"`, `linux`, `macos`, `windows` the OS and its family +// `os = "…"`, a bareword naming a system the OS and its family // `family = "…"`, `unix` the family // `arch = "…"`, `env = "…"` that component // `all(a, b, …)` the union of its terms @@ -53,9 +53,16 @@ inline constexpr std::string_view kCfgLayerKeys[] = { "c++-abi", "c-abi", "compiler", "compiler-runtime", "kernel-abi", }; -inline constexpr std::string_view kCfgBarewords[] = { - "linux", "macos", "unix", "windows", -}; +// A BAREWORD NAMES A SYSTEM, AND THE ROWS ARE ITS VOCABULARY. `unix` is the +// one word that names a family (unix | windows, the row's `family`); every +// other identifier without a `-` is `os = ""`: `linux`, `macos`, +// `windows`, `freebsd`, and the system of any row a platform defines, with no +// list here to extend. A `-` makes a key a triple, never a bareword. +inline constexpr std::string_view kCfgFamilyBareword = "unix"; +constexpr bool is_bareword(std::string_view word) { + return !word.empty() && word.find('-') == std::string_view::npos + && word.find('(') == std::string_view::npos; +} // The rank of a selector: the number of target-triple components it fixes, or // `kTripleRank` for a bare triple. Larger is more specific. @@ -89,9 +96,8 @@ unsigned component_of_key(std::string_view key) { } unsigned component_of_bareword(std::string_view word) { - if (word == "linux" || word == "macos" || word == "windows") return kOs | kFamily; - if (word == "unix") return kFamily; - return 0; + if (!is_bareword(word)) return 0; + return word == kCfgFamilyBareword ? kFamily : kOs | kFamily; } // The grammar of `cfg(...)`: all(list) | any(list) | not(expr) | key = "value" diff --git a/modules/toolchain-model/build.mcpp b/modules/toolchain-model/build.mcpp index cc6dc2401..80cd9d78a 100644 --- a/modules/toolchain-model/build.mcpp +++ b/modules/toolchain-model/build.mcpp @@ -16,7 +16,7 @@ namespace { constexpr std::string_view kRowKeys[] = { "triple", "tier", "note", "standard", "exact", "march", "mabi", "code-model", "multilib", "flags", - "link-emulation", "clang-triple", + "link-emulation", "clang-triple", "family", }; constexpr std::string_view kProviderKeys[] = { "name", "serves", "priority", "hosts", "probe", "toolchain", "pairs", "sysroot", "linkage", @@ -100,6 +100,11 @@ std::string row_entry(const toml::Table& t, Arrays& arrays, std::set 3 || std::ranges::any_of(seg, [](auto const& x) { return x.empty(); })) throw Failure{std::format("{}: a triple is `arch-os` or `arch-os-env`", where)}; + // A row may state its system's family (`unix` | `windows`); a system the + // engine has always known answers it by convention when the row is silent. + const auto family = text(t, "family", where); + if (!family.empty() && family != "unix" && family != "windows") + throw Failure{std::format("{}: `family` is `unix` or `windows`, not `{}`", where, family)}; bool exact = false; if (auto it = t.find("exact"); it != t.end()) { if (!it->second.is_bool()) throw Failure{std::format("{}: `exact` is not a boolean", where)}; @@ -108,13 +113,13 @@ std::string row_entry(const toml::Table& t, Arrays& arrays, std::set& rows) { diff --git a/modules/toolchain-model/data/builtin.toml b/modules/toolchain-model/data/builtin.toml index 0d9014a89..4629e010d 100644 --- a/modules/toolchain-model/data/builtin.toml +++ b/modules/toolchain-model/data/builtin.toml @@ -28,6 +28,8 @@ # does not # clang-triple the triple the compiler is given, when the system's spelling # is not derived from the identity (`x86_64-unknown-freebsd14.0`) +# family the system's family, `unix` or `windows` (`cfg(unix)`); a +# system the engine has always known answers it by convention # march, mabi, code-model, multilib, flags, link-emulation # the ISA profile of a bare-metal row: `-march`, `-mabi`, # `-mcmodel` (empty: the driver's default), the multilib @@ -169,24 +171,28 @@ standard = false # COMPAT_FREEBSD14, on 15. [[platform.define]] triple = "x86_64-freebsd" +family = "unix" tier = "preview" standard = true clang-triple = "x86_64-unknown-freebsd14.0" [[platform.define]] triple = "aarch64-freebsd" +family = "unix" tier = "preview" standard = true clang-triple = "aarch64-unknown-freebsd14.0" [[platform.define]] triple = "x86_64-freebsd-musl" +family = "unix" tier = "preview" standard = false clang-triple = "x86_64-unknown-freebsd14.0" [[platform.define]] triple = "aarch64-freebsd-musl" +family = "unix" tier = "preview" standard = false clang-triple = "aarch64-unknown-freebsd14.0" diff --git a/modules/toolchain-model/src/triple.cppm b/modules/toolchain-model/src/triple.cppm index fe2dfdbb7..60df8b5bd 100644 --- a/modules/toolchain-model/src/triple.cppm +++ b/modules/toolchain-model/src/triple.cppm @@ -410,6 +410,10 @@ struct Triple { // nothing, unchanged: `cfg(unix)` on bare metal would be false in a way no // source could act on. std::string family() const { + // The row's own statement first (`family`, built-in or defined), then + // the convention of the systems the engine has always known. + if (auto* r = mcpp::toolchain::target::find_row(str()); r && !r->family.empty()) + return std::string(r->family); if (auto* d = defined()) return std::string(d->family); if (os == "windows") return "windows"; if (os == "linux" || os == "macos" || os == "ios" diff --git a/src/build/prepare_inputs.cppm b/src/build/prepare_inputs.cppm index a8a5bd6bb..6049aa73f 100644 --- a/src/build/prepare_inputs.cppm +++ b/src/build/prepare_inputs.cppm @@ -27,6 +27,7 @@ import mcpp.toolchain.apple_sdk; import mcpp.toolchain.model; import mcpp.toolchain.fingerprint; import mcpp.toolchain.triple; +import mcpp.toolchain.target_rows; import mcpp.ui; export namespace mcpp::build { @@ -206,7 +207,7 @@ using mcpp::manifest::cfg::kCfgTripleKeys; // either; only the schedule question (`uses_layer`) distinguishes them. using mcpp::manifest::cfg::kCfgEarlyLayerKeys; using mcpp::manifest::cfg::kCfgLayerKeys; -using mcpp::manifest::cfg::kCfgBarewords; +using mcpp::manifest::cfg::kCfgFamilyBareword; // Answerable before resolution. Its value comes from the build's own accel. inline bool is_cfg_early_layer_key(std::string_view k) { @@ -267,11 +268,10 @@ struct Parser { } bool match_alias(const std::string& a) { if (seenWords) seenWords->push_back(a); - if (a == "windows") return c.os == "windows"; - if (a == "linux") return c.os == "linux"; - if (a == "macos") return c.os == "macos"; - if (a == "unix") return c.family == "unix"; - return false; // unknown bareword → no match, and `seenWords` reports it + if (a == kCfgFamilyBareword) return c.family == a; + // Any other word names a system: `os = ""`. A word no row names + // matches nothing, and `seenWords` reports it. + return mcpp::manifest::cfg::is_bareword(a) && c.os == a; } bool match_kv(const std::string& k, const std::string& v) { if (seenKeys) seenKeys->push_back(k); @@ -331,10 +331,9 @@ inline bool matches(const std::string& predicate, const Ctx& c) { return p.expr(); } // Bare OS/family alias sugar: `[target.linux]` ≡ `[target.'cfg(linux)']`. - // These aliases are never valid triples (no dash), so there is no ambiguity + // A bareword is never a valid triple (no dash), so there is no ambiguity // with the exact-triple namespace. Evaluated as the cfg bareword. - if (predicate == "windows" || predicate == "linux" || - predicate == "macos" || predicate == "unix") { + if (mcpp::manifest::cfg::is_bareword(predicate)) { Parser p{ predicate, 0, c }; return p.expr(); } @@ -423,8 +422,7 @@ inline std::vector os_only_platforms(const std::string& predicate) // `Parser::expr()` in `matches()` — so both are eligible here. Anything // else (an exact triple, or the unparsed escape hatch) names neither an // OS nor a platform on its own. - static constexpr std::string_view kBareAliases[] = { "linux", "macos", "unix", "windows" }; - if (!wrapped && std::ranges::find(kBareAliases, predicate) == std::end(kBareAliases)) + if (!wrapped && !mcpp::manifest::cfg::is_bareword(predicate)) return {}; std::string_view inner = wrapped ? text.substr(4, text.size() - 5) : text; @@ -477,6 +475,20 @@ inline bool uses_layer(const std::string& predicate) { // evaluate to false in silence, which is indistinguishable from a predicate // that correctly did not apply — so `[target.'cfg(c-abi = "musl")'.build]` was // dropped without a word for the entire time docs/14 documented it. +// The systems the rows name (built-in and defined), and the family word. +inline std::vector system_barewords() { + std::set systems; + for (auto const* r : mcpp::toolchain::target::rows()) + if (!r->os.empty()) systems.emplace(r->os); + std::vector out{ std::string(kCfgFamilyBareword) }; + out.insert(out.end(), systems.begin(), systems.end()); + return out; +} +inline bool known_bareword(std::string_view w) { + if (w == kCfgFamilyBareword) return true; + return std::ranges::any_of(mcpp::toolchain::target::rows(), [&](auto const* r) { return r->os == w; }); +} + inline std::vector unknown_tokens(const std::string& predicate) { auto scan = scan_predicate(predicate); std::vector out; @@ -489,7 +501,7 @@ inline std::vector unknown_tokens(const std::string& predicate) { && !is_cfg_layer_key(k)) add(k); for (auto const& w : scan.barewords) - if (std::ranges::find(kCfgBarewords, w) == std::end(kCfgBarewords)) + if (!known_bareword(w)) add(w); return out; } @@ -499,8 +511,9 @@ inline std::string vocabulary_sentence() { std::string keys, words; for (auto k : kCfgTripleKeys) { if (!keys.empty()) keys += ", "; keys += k; } for (auto k : kCfgLayerKeys) { if (!keys.empty()) keys += ", "; keys += k; } - for (auto w : kCfgBarewords) { if (!words.empty()) words += ", "; words += w; } - return std::format("Supported keys: {}. Supported barewords: {}.", keys, words); + for (auto const& w : system_barewords()) { if (!words.empty()) words += ", "; words += w; } + return std::format("Supported keys: {}. Supported barewords: {}, and the system of a row a platform " + "defines.", keys, words); } } // namespace cfgpred diff --git a/tests/fixtures/target-rows.snapshot b/tests/fixtures/target-rows.snapshot index 78bc04f8e..712dc7e6c 100644 --- a/tests/fixtures/target-rows.snapshot +++ b/tests/fixtures/target-rows.snapshot @@ -308,7 +308,7 @@ row x86_64-freebsd llvm x86_64-unknown-freebsd14.0 llvm@15.0 x86_64-unknown-freebsd14.0 format ELF - family + family unix pe/macho/wasm 000 apple/ios/sim/android 0000 freestanding/openkal/own-sysroot/capability 0000 @@ -327,7 +327,7 @@ row aarch64-freebsd llvm aarch64-unknown-freebsd14.0 llvm@15.0 aarch64-unknown-freebsd14.0 format ELF - family + family unix pe/macho/wasm 000 apple/ios/sim/android 0000 freestanding/openkal/own-sysroot/capability 0000 @@ -346,7 +346,7 @@ row x86_64-freebsd-musl llvm x86_64-unknown-freebsd14.0 llvm@15.0 x86_64-unknown-freebsd14.0 format ELF - family + family unix pe/macho/wasm 000 apple/ios/sim/android 0000 freestanding/openkal/own-sysroot/capability 0001 @@ -365,7 +365,7 @@ row aarch64-freebsd-musl llvm aarch64-unknown-freebsd14.0 llvm@15.0 aarch64-unknown-freebsd14.0 format ELF - family + family unix pe/macho/wasm 000 apple/ios/sim/android 0000 freestanding/openkal/own-sysroot/capability 0001 diff --git a/tests/unit/test_cfg_barewords.cpp b/tests/unit/test_cfg_barewords.cpp new file mode 100644 index 000000000..e3242bce1 --- /dev/null +++ b/tests/unit/test_cfg_barewords.cpp @@ -0,0 +1,52 @@ +import std; +import mcpplibs.mtest; +import mcpp.build.prepare_inputs; +import mcpp.manifest; + +using namespace mcpplibs::mtest; + +// A cfg bareword is data, not a list (docs/22 §target sections): `unix` is +// the family word, and any other dash-free word is `os = ""`. The +// systems mcpp names are the rows' systems, and a row's `family` states its +// family, so a system a row adds is selectable without a new release. + +namespace cfgpred = mcpp::build::cfgpred; + +namespace { +bool m(std::string_view predicate, std::string_view triple) { + return cfgpred::matches(std::string(predicate), cfgpred::context_for(std::string(triple))); +} +} // namespace + +UTest a_bareword_is_its_os{"CfgBarewords/ABarewordIsItsOs", [] { + expect(m("freebsd", "x86_64-freebsd")); + expect(m("cfg(freebsd)", "x86_64-freebsd-musl")); + expect(m(R"(cfg(all(freebsd, arch = "x86_64")))", "x86_64-freebsd")); + expect(!m("freebsd", "x86_64-linux-musl")); + expect(m("linux", "x86_64-linux-musl")); + expect(!m("linux", "x86_64-freebsd")); +}}; + +UTest the_family_comes_from_the_row{"CfgBarewords/TheFamilyComesFromTheRow", [] { + expect(m("unix", "x86_64-freebsd")); + expect(m("cfg(unix)", "aarch64-freebsd-musl")); + expect(m("unix", "x86_64-linux-gnu")); + expect(!m("unix", "x86_64-windows-msvc")); + expect(eq(cfgpred::context_for("x86_64-freebsd-musl").family, "unix")); +}}; + +UTest a_triple_is_not_a_bareword{"CfgBarewords/ATripleIsNotABareword", [] { + expect(mcpp::manifest::cfg::is_bareword("freebsd")); + expect(!mcpp::manifest::cfg::is_bareword("x86_64-freebsd")); + expect(!mcpp::manifest::cfg::is_bareword("cfg(unix)")); + expect(!mcpp::manifest::cfg::is_bareword("")); +}}; + +UTest an_unknown_word_is_reported{"CfgBarewords/AnUnknownWordIsReported", [] { + expect(eq(cfgpred::unknown_tokens("cfg(freebds)"), std::vector({"freebds"}))); + expect(cfgpred::unknown_tokens("cfg(any(freebsd, unix, linux, macos, windows))").empty()); + const auto words = cfgpred::system_barewords(); + expect(std::ranges::find(words, "unix") != words.end()); + expect(std::ranges::find(words, "freebsd") != words.end()); + expect(std::ranges::find(words, "linux") != words.end()); +}}; From 8a64800935e47b17309578a9c2dc26dbafda38d9 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Wed, 11 Nov 2026 00:08:57 +0900 Subject: [PATCH 05/13] A namespace's package may be named version, path, git or workspace (#918) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A table is one dependency specification when its `path`, `version` or `git` is a string or its `workspace` a boolean. `gpp.version = { path = "…" }` declares the package `gpp.version`; it was taken as the specification of `gpp` and refused for naming no source. Unit test Manifest/APackageNamedLikeASpecField; e2e 1074. --- modules/manifest/src/toml.cppm | 15 +++--- ...mespace_package_named_like_a_spec_field.sh | 46 +++++++++++++++++++ tests/unit/test_manifest.cpp | 28 +++++++++++ 3 files changed, 83 insertions(+), 6 deletions(-) create mode 100755 tests/e2e/1074_a_namespace_package_named_like_a_spec_field.sh diff --git a/modules/manifest/src/toml.cppm b/modules/manifest/src/toml.cppm index 93487e1ae..f120a9ceb 100644 --- a/modules/manifest/src/toml.cppm +++ b/modules/manifest/src/toml.cppm @@ -2398,14 +2398,17 @@ std::expected parse_document(const t::Document& documen // property #349 established for the index floor: data must not be able to // decide whether the program works. // - // An identity key is an unambiguous discriminator: a nested namespace - // table's keys are PACKAGE names, and no package is named `version` / - // `path` / `git` / `workspace`. + // An identity key with an identity value is the discriminator: `path` / + // `version` / `git` are strings and `workspace` is a boolean in a spec. A + // nested namespace table's keys are PACKAGE names, and a package may be + // named `version` (#918: `gpp.version = { path = "../version" }`), so the + // same key holding a table is that package, not the spec's field. auto looks_like_inline_dep_spec = [](const t::Table& sub) { - if (sub.empty()) return false; - for (auto& [sk, sv] : sub) - if (sk == "path" || sk == "version" || sk == "git" || sk == "workspace") + for (auto& [sk, sv] : sub) { + if ((sk == "path" || sk == "version" || sk == "git") && sv.is_string()) return true; + if (sk == "workspace" && sv.is_bool()) return true; + } return false; }; diff --git a/tests/e2e/1074_a_namespace_package_named_like_a_spec_field.sh b/tests/e2e/1074_a_namespace_package_named_like_a_spec_field.sh new file mode 100755 index 000000000..cb6fcf126 --- /dev/null +++ b/tests/e2e/1074_a_namespace_package_named_like_a_spec_field.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +# 1074 -- a namespace's package may be named like a dependency specification's +# field (#918; docs/06). +# +# `gpp.version = { path = "../version" }` is TOML for the table `gpp` holding the +# key `version`, whose value is a table: the package `version` in the namespace +# `gpp`. A specification's `path`, `version` and `git` are strings and its +# `workspace` a boolean, so only such a value makes a table one specification. +# +# Criteria: a project depending on `gpp.version` by path builds and runs it, and +# `mcpp emit build-database` describes it. +set -e +TMP=$(mktemp -d) +trap 'rm -rf "$TMP"' EXIT +fail() { echo "FAIL: $1"; shift; for f in "$@"; do echo "--- $f ---"; tail -30 "$f" 2>/dev/null; done; exit 1; } + +mkdir -p "$TMP/version/src" "$TMP/app/src" +cat > "$TMP/version/mcpp.toml" <<'T' +[package] +namespace = "gpp" +name = "version" +version = "0.1.0" +T +cat > "$TMP/version/src/version.cppm" <<'T' +export module gpp.version; +export int gpp_version() { return 7; } +T +cat > "$TMP/app/mcpp.toml" <<'T' +[package] +name = "app" +version = "0.1.0" + +[dependencies] +gpp.version = { path = "../version" } +T +cat > "$TMP/app/src/main.cpp" <<'T' +import gpp.version; +int main() { return gpp_version() == 7 ? 0 : 1; } +T + +cd "$TMP/app" +"$MCPP" run > run.log 2>&1 || fail "the package gpp.version was not read as a package" run.log +grep -q 'must specify' run.log && fail "the namespace was read as one specification" run.log +"$MCPP" emit build-database --format json > db.json 2> db.err || fail "the build database was not described" db.err +grep -q 'version.cppm' db.json || fail "the build database does not hold gpp.version" db.json +echo "OK" diff --git a/tests/unit/test_manifest.cpp b/tests/unit/test_manifest.cpp index 6f027896a..6693562bf 100644 --- a/tests/unit/test_manifest.cpp +++ b/tests/unit/test_manifest.cpp @@ -2502,6 +2502,34 @@ ylib = { path = "ylib" } expect(s.version.empty()); }}; +UTest a_package_named_like_a_spec_field{"Manifest/APackageNamedLikeASpecField", [] { + // #918: `gpp.version = { path = ... }` is the package `version` in the + // namespace `gpp`. A spec's `version` is a string; a table under the same + // key is a package, in [dependencies] and in [workspace.dependencies]. + constexpr auto src = R"( +[package] +name = "app" +version = "0.1.0" + +[dependencies] +gpp.core = { path = "../core" } +gpp.version = { path = "../version" } +solo = { version = "2.0.0" } + +[workspace.dependencies] +gpp.git = { path = "../git" } +)"; + auto m = mcpp::manifest::parse_string(src); + if (auto&& failed = expect(fatal(m.has_value())); !failed) failed << m.error().format(); + expect(fatal(m->dependencies.contains("gpp.version"))); + expect(eq(m->dependencies.at("gpp.version").path, "../version")); + expect(eq(m->dependencies.at("gpp.core").path, "../core")); + expect(eq(m->dependencies.at("solo").version, "2.0.0")); + expect(!m->dependencies.contains("gpp")); + expect(fatal(m->workspace.dependencies.contains("gpp.git"))); + expect(eq(m->workspace.dependencies.at("gpp.git").path, "../git")); +}}; + UTest no_workspace_section_means_not_present{"Manifest/NoWorkspaceSectionMeansNotPresent", [] { constexpr auto src = R"( [package] From 5e4f74f156532708663c79d7b0540b53735fda96 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Wed, 11 Nov 2026 00:08:57 +0900 Subject: [PATCH 06/13] A platform chosen for a request serves it, by whichever selector chose it A platform package chosen for a request that no built-in provider names keeps the providers of other platform packages out of the selection, so `-freebsd` keeps the system's row when `cfg(os = "freebsd")` or `[target.freebsd]` chose its platform, as an exact-row section did; with no platform chosen the musl identity is taken (e2e 1059, unit tests TargetSelectPlatform). The capability-pin set includes the FreeBSD musl rows. --- docs/21-the-target-triple.md | 2 +- docs/zh/21-the-target-triple.md | 2 +- .../toolchain-model/src/target_select.cppm | 4 ++ src/build/prepare/platform.cpp | 8 +++- src/build/prepare/state.cppm | 9 +++- src/build/prepare/toolchain.cpp | 8 +++- tests/unit/test_target_select_platform.cpp | 44 +++++++++++++++++++ tests/unit/test_toolchain_triple.cpp | 2 + 8 files changed, 74 insertions(+), 5 deletions(-) create mode 100644 tests/unit/test_target_select_platform.cpp diff --git a/docs/21-the-target-triple.md b/docs/21-the-target-triple.md index 7320bfaef..0020b6710 100644 --- a/docs/21-the-target-triple.md +++ b/docs/21-the-target-triple.md @@ -573,7 +573,7 @@ vocabulary, nothing wired yet. | `*-linux-gnu` | Linux, same arch only | additionally needs the host-native `xim:glibc` / `xim:linux-headers` | | `x86_64-windows-gnu` | Linux and Windows by the gcc payload; every host by the MinGW-w64 base package | one identity, host-split at the distribution layer; the `mingw-llvm` provider serves it with clang and `xim:mingw-w64-sysroot` (llvm-mingw's target side: MinGW-w64 on UCRT, libc++, compiler-rt) where no gcc payload exists | | `aarch64-windows-gnu` | every host | the MinGW-w64 base package alone; no gcc payload targets it | -| `*-freebsd` | every host, through a platform | the rows are built-in; a platform names each identity's FreeBSD base package (`xim:x86_64-freebsd-sysroot`, `xim:aarch64-freebsd-sysroot`) and is selected with `[target.] platform` | +| `*-freebsd` | every host, through a platform | the rows are built-in; a platform names each identity's FreeBSD base package (`xim:x86_64-freebsd-sysroot`, `xim:aarch64-freebsd-sysroot`) and is selected with `[target.] platform`, or by any selector the row meets (`[target.freebsd]`, `cfg(os = "freebsd")`); another platform package's provider does not compete with the chosen platform | | `*-freebsd-musl` | every host, through the graph | openkal-platform's hosted part (0.26.0): openkal-musl over openkal-freebsd standalone, one static program; a request of `-freebsd` with no platform selected for it takes this identity (2026.11.10.2+), as `aarch64-macos` takes the musl identity on a host that is not a Mac | | `x86_64-windows-msvc` | Windows | MSVC is located on the machine | | `x86_64-windows-musl` | Windows by payload; anywhere by graph | no gcc emits PE+musl, and LLVM cannot spell the triple | diff --git a/docs/zh/21-the-target-triple.md b/docs/zh/21-the-target-triple.md index 541cd445f..424c4d437 100644 --- a/docs/zh/21-the-target-triple.md +++ b/docs/zh/21-the-target-triple.md @@ -530,7 +530,7 @@ system · `系统` 在机器上被找到,不是 mcpp 安装的 · `SDK` 平台 | `*-linux-gnu` | Linux,且仅同架构 | 还需要本机架构的 `xim:glibc` / `xim:linux-headers` | | `x86_64-windows-gnu` | Linux 与 Windows 经 gcc 载荷;每一台宿主经 MinGW-w64 基座包 | 一个身份,只在分发层按宿主拆分;没有 gcc 载荷之处,`mingw-llvm` 提供者以 clang 与 `xim:mingw-w64-sysroot`(llvm-mingw 的目标侧:UCRT 上的 MinGW-w64、libc++、compiler-rt)服务它 | | `aarch64-windows-gnu` | 每一台宿主 | 只由 MinGW-w64 基座包服务;没有 gcc 载荷以它为目标 | -| `*-freebsd` | 每一台宿主,经平台 | 行是内置的;平台为每个身份指名 FreeBSD 基座包(`xim:x86_64-freebsd-sysroot`、`xim:aarch64-freebsd-sysroot`),以 `[target.<行>] platform` 选择 | +| `*-freebsd` | 每一台宿主,经平台 | 行是内置的;平台为每个身份指名 FreeBSD 基座包(`xim:x86_64-freebsd-sysroot`、`xim:aarch64-freebsd-sysroot`),以 `[target.<行>] platform` 或该行满足的任一选择器(`[target.freebsd]`、`cfg(os = "freebsd")`)选择;其他平台包的提供者不与所选平台竞争 | | `*-freebsd-musl` | 每一台宿主,经依赖图 | openkal-platform 的 hosted 部分(0.26.0):openkal-freebsd 的 standalone 形态之上的 openkal-musl,一个静态程序;未为 `-freebsd` 选平台时,该请求取这一身份(2026.11.10.2+),正如非 Mac 宿主上的 `aarch64-macos` 取 musl 身份 | | `x86_64-windows-msvc` | Windows | MSVC 是在机器上被找到的 | | `x86_64-windows-musl` | payload 只在 Windows 上;图则任意宿主 | 没有 gcc 能发出 PE + musl,且 LLVM 拼不出这个三元组 | diff --git a/modules/toolchain-model/src/target_select.cppm b/modules/toolchain-model/src/target_select.cppm index 564a91831..506676fd2 100644 --- a/modules/toolchain-model/src/target_select.cppm +++ b/modules/toolchain-model/src/target_select.cppm @@ -45,6 +45,9 @@ struct Context { std::string provider; // `--platform none`: no provider a platform package implements serves. bool platformPackages = true; + // A platform package chosen for the request that no built-in provider + // names: the providers of other platform packages do not serve it. + std::function platformChosen; }; struct Selection { @@ -105,6 +108,7 @@ Selection select(std::string_view request, std::string_view arch, std::string_vi if (!serves(*p, row.triple)) continue; if (!ctx.provider.empty() && p->name != ctx.provider) continue; if (!ctx.platformPackages && !p->platform.empty()) continue; + if (ctx.platformChosen && !p->platform.empty() && !ctx.platformChosen(p->platform)) continue; served = true; Candidate c{ &row, p, p->priority, true, {} }; if (ctx.priority) diff --git a/src/build/prepare/platform.cpp b/src/build/prepare/platform.cpp index d83d0eef8..2fa18e722 100644 --- a/src/build/prepare/platform.cpp +++ b/src/build/prepare/platform.cpp @@ -298,8 +298,13 @@ void define_early_platform(PrepareState& state) { state.provisionalTarget = true; } +std::string platform_short_name(std::string_view ref) { + auto r = mp::parse_ref_text(ref); + return r ? known_short_name(*r) : std::string{}; +} + std::string named_provider(const PrepareState& state, const mcpp::toolchain::triple::Triple& t, - std::span config) { + std::span config, std::string* platform) { const auto flag = !state.overrides.platform_choice.empty() ? state.overrides.platform_choice : mcpp::invocation::get("MCPP_PLATFORM").value_or(""); @@ -317,6 +322,7 @@ std::string named_provider(const PrepareState& state, const mcpp::toolchain::tri auto ref = mp::parse_ref_text(p->platform); if (ref && ref->spec.shortName == chosen) return std::string(p->name); } + if (platform) *platform = chosen; return {}; } diff --git a/src/build/prepare/state.cppm b/src/build/prepare/state.cppm index 47d39ccae..b69abbd96 100644 --- a/src/build/prepare/state.cppm +++ b/src/build/prepare/state.cppm @@ -1314,8 +1314,15 @@ void define_platform(const mcpp::manifest::platform::Statement& s, std::string_v // manifest is on this machine (a directory, or the second pass's root); and a // provisional row for a request only a chosen platform can define. void define_early_platform(PrepareState& state); +// The provider chosen by name for `t` (`builtin:`, or the platform package +// a built-in provider names); `none` for `--platform none`. A platform package no +// built-in provider names leaves it empty and is reported in `platform` (its +// short name). std::string named_provider(const PrepareState& state, const mcpp::toolchain::triple::Triple& t, - std::span config); + std::span config, + std::string* platform = nullptr); +// The short name of the package a reference names (`path:` reads its manifest). +std::string platform_short_name(std::string_view ref); void step4b_seed_platform(PrepareState& state); std::expected step4b_apply_platform(PrepareState& state); diff --git a/src/build/prepare/toolchain.cpp b/src/build/prepare/toolchain.cpp index aa2346fc3..859aec7bc 100644 --- a/src/build/prepare/toolchain.cpp +++ b/src/build/prepare/toolchain.cpp @@ -616,11 +616,17 @@ step1_resolve_target_triple_request(PrepareState& state, TargetOverrideCtx& ctx) family = std::string(mcpp::toolchain::family_name(spec->family)); std::vector config; if (auto cfg = state.get_cfg(true); cfg) config = (*cfg)->platformOverrides; - const std::string provider = named_provider(state, *ctx.parsed, config); + std::string platform; + const std::string provider = named_provider(state, *ctx.parsed, config, &platform); auto sctx = target_context(state.m->platformOverrides, config, family, provider == "none" ? std::string{} : provider, state.msvc_usable_either_origin); sctx.platformPackages = provider != "none"; + // A platform the project or the machine chose for the request serves it: + // another package's provider (openkal's musl identity of the system) is + // not a candidate, and the request's own row waits for the platform's. + if (!platform.empty()) + sctx.platformChosen = [platform](std::string_view ref) { return platform_short_name(ref) == platform; }; ctx.sel = mcpp::toolchain::target::select(state.overrides.target_triple, ctx.parsed->arch, ctx.parsed->os, ctx.parsed->env, ctx.parsed->envExplicit, sctx); diff --git a/tests/unit/test_target_select_platform.cpp b/tests/unit/test_target_select_platform.cpp new file mode 100644 index 000000000..3d723826b --- /dev/null +++ b/tests/unit/test_target_select_platform.cpp @@ -0,0 +1,44 @@ +import std; +import mcpplibs.mtest; +import mcpp.toolchain.target_select; + +using namespace mcpplibs::mtest; + +// A request selects among the rows it reaches and the providers that serve them +// (SPEC-016 §4). `-freebsd` reaches the system's row, which a platform +// serves, and the musl identity, which openkal-platform serves; with no platform +// chosen the latter is taken. A platform the project chose for the request that +// no built-in provider names serves it: another package's provider does not +// compete, so the request keeps the system's row for the chosen platform. + +namespace target = mcpp::toolchain::target; + +namespace { +target::Context on_linux() { + target::Context c; + c.host = target::host_pair("linux", "x86_64"); + return c; +} +} // namespace + +UTest no_platform_takes_the_musl_identity{"TargetSelectPlatform/NoPlatformTakesTheMuslIdentity", [] { + auto s = target::select("x86_64-freebsd", "x86_64", "freebsd", "", false, on_linux()); + expect(fatal(s.row != nullptr)); + expect(eq(std::string(s.row->triple), "x86_64-freebsd-musl")); +}}; + +UTest a_chosen_platform_keeps_the_system_row{"TargetSelectPlatform/AChosenPlatformKeepsTheSystemRow", [] { + auto c = on_linux(); + c.platformChosen = [](std::string_view ref) { return ref == "path:/toy"; }; + auto s = target::select("x86_64-freebsd", "x86_64", "freebsd", "", false, c); + expect(fatal(s.row != nullptr)); + expect(eq(std::string(s.row->triple), "x86_64-freebsd")); + for (auto const& cand : s.candidates) + if (cand.provider) expect(cand.provider->platform.empty()) << cand.provider->name; +}}; + +UTest a_written_env_is_kept{"TargetSelectPlatform/AWrittenEnvIsKept", [] { + auto s = target::select("x86_64-freebsd-musl", "x86_64", "freebsd", "musl", true, on_linux()); + expect(fatal(s.row != nullptr)); + expect(eq(std::string(s.row->triple), "x86_64-freebsd-musl")); +}}; diff --git a/tests/unit/test_toolchain_triple.cpp b/tests/unit/test_toolchain_triple.cpp index 0b7874fa2..74df15d30 100644 --- a/tests/unit/test_toolchain_triple.cpp +++ b/tests/unit/test_toolchain_triple.cpp @@ -760,6 +760,8 @@ UTest exactly_these_rows_have_a_capability_pin{"Triple/ExactlyTheseRowsHaveACapa "x86_64-windows-musl", // musl on macOS: openkal-platform's hosted part, which pairs with clang only. "aarch64-macos-musl", "x86_64-macos-musl", + // musl on FreeBSD: the same hosted part over openkal-freebsd (design 2026-11-10 K9). + "aarch64-freebsd-musl", "x86_64-freebsd-musl", "wasm32-emscripten", "aarch64-linux-android", "x86_64-linux-android", // Ok images: clang and lld emit them on every host, as for bare metal. From cdf7beba3634dea77a7e18614ef94544465603e8 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Wed, 11 Nov 2026 00:08:57 +0900 Subject: [PATCH 07/13] CHANGELOG and design record: barewords, #918, the chosen platform --- ...026-11-10-cross-platform-ecosystem-design.md | 4 +++- CHANGELOG.md | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/.agents/docs/2026-11-10-cross-platform-ecosystem-design.md b/.agents/docs/2026-11-10-cross-platform-ecosystem-design.md index 7c33a08a2..0be0d61d2 100644 --- a/.agents/docs/2026-11-10-cross-platform-ecosystem-design.md +++ b/.agents/docs/2026-11-10-cross-platform-ecosystem-design.md @@ -6,7 +6,7 @@ status: active # 生态方案:跨平台通用基础设施(mcpp + openkal + xim),以一个 C89 工程为验证 **日期:** 2026-11-10 -**状态:** 第四版,mcpp 部分已在 2026.11.10.1 实施,K9 与 I1 的补正在 2026.11.10.2。Q1–Q6 已定稿(第 11.1 节);O1–O4 已按推荐实施,实施中的调整见第 11.2 节;第 12 节为两项 +**状态:** 第四版,mcpp 部分已在 2026.11.10.1 实施,K9、E15、I1 的补正与 #918 的修正在 2026.11.10.2。Q1–Q6 已定稿(第 11.1 节);O1–O4 已按推荐实施,实施中的调整见第 11.2 节;第 12 节为两项 风险的说明,第 13 节为多视角深度自审;第 15 节为实施记录,第 16 节为测试体系向 mtest 的迁移 **范围:** mcpp(引擎与内置数据);openkal 家族(openkal 规范、openkal-linux/macos/windows、openkal-musl、 openkal-llvm-runtime、openkal-image、openkal-platform、openkal-conformance,新增 openkal-freebsd、openkal-posix); @@ -594,6 +594,8 @@ B 路线在 Windows 上就是正确的默认。 | 实施中发现并修复 | 工具链为另一目标构建的 C++ 归档(其父目录的三元组与目标的架构或系统不同)不链接,并给出降级诊断;ok 映像的启动器依赖 mcpplibs.os 0.4.4(openkal 0.24 与 0.25 两族均可);交叉 gcc 自身的 Windows 头文件属于工具链(`mingw` 提供者下资源脚本的 `"winres.h"`);资源脚本中各处都找不到、也无构建动作写出的带引号 include 不进入构建图,由脚本的预处理与资源编译器处理 | 单元测试 `Distribution/ForeignArchivesAreNotLinked`;mingw 交叉打包;e2e 1058、1072(验证工程的 Windows 行暴露) | | K9(mcpp 2026.11.10.2) | `-freebsd-musl` 两行由 openkal 提供者经 openkal-platform 0.26.0 的 hosted 部分服务(openkal-freebsd standalone 之上的 openkal-musl 0.29.2);未为 `-freebsd` 选平台时取该身份,选了平台则保留系统 ABI;openkal-run 0.6.1 在 FreeBSD 上以 openkal-freebsd 为缺省实现,okrun 由两条路线构建;平台的运行器主机加入 FreeBSD | e2e 1073、1059;openkal-platform CI 的 freebsd 作业(FreeBSD 虚拟机中运行程序,并以 FreeBSD 的 okrun 运行 ok 映像) | | I1 的补正(mcpp 2026.11.10.2) | MSVC 载荷的 `c-abi` 回答 `ucrt`(此前为工具集名 `msvc`),`compat.glfw` 的 `requires = ["mcpp:c-abi=ucrt"]` 在 MSVC 行上成立;SPEC-002 v1.7 写明段与 C 库名的对应 | 单元测试 `TargetSideResolve`;mcpp-index#748 的 Windows 作业 | +| E15(mcpp 2026.11.10.2) | cfg 裸词由数据决定:`unix` 为族词,其余不含短横线的词即 `os = "<词>"`;行表的 `family` 陈述族,FreeBSD 各行属 `unix` 族;词表与诊断由行的系统生成,平台定义的系统同样可作裸词 | 单元测试 `CfgBarewords`;docs/22 | +| #918 的修正(mcpp 2026.11.10.2) | 依赖表仅当 `path`/`version`/`git` 为字符串或 `workspace` 为布尔时视为单个依赖说明,命名空间中名为 `version` 等的包按包读取 | 单元测试 `Manifest/APackageNamedLikeASpecField` | openkal 家族(K5、K6,openkal 0.25.0)、openkal-freebsd 0.1.0(hosted 与 standalone 两种形态,x86_64 与 arm64)、 openkal-musl 0.29.1 与 openkal-llvm-runtime 0.20.1(FreeBSD 的 standalone C 与 C++ 运行时)以及 mcpplibs/os 的实施记录 diff --git a/CHANGELOG.md b/CHANGELOG.md index ba035f52c..315ecaa4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,16 @@ of the system beneath. A request of `-freebsd` with no platform selected for it takes this identity, as `aarch64-macos` takes the musl identity on a host that is not a Mac; a project that selects a platform for `-freebsd` - keeps the system's own ABI. + keeps the system's own ABI, by whichever selector chose it (`[target.]`, + `[target.freebsd]` or `cfg(os = "freebsd")`): a platform package chosen for a + request that no built-in provider names serves it, and another package's + provider does not compete with it. +- A cfg bareword names any system a row names: `unix` is the family word, and + any other word without a dash is `os = ""`, so `[target.freebsd]`, + `cfg(freebsd)` and the system of a row a platform defines select as `linux` + does. A row states its family (`family`, `unix` or `windows`), and FreeBSD's + rows are of the `unix` family, so `cfg(unix)` holds on them. A word that + names no row's system is reported as before. ### Changed @@ -32,6 +41,12 @@ It was answered as `msvc`, so `requires = ["mcpp:c-abi=ucrt"]` (a Win32 backend's statement of its C runtime) refused the MSVC route while the GNU routes satisfied it. SPEC-002 v1.7 states the names. +- A dependency namespace holding a package named `version`, `path`, `git` or + `workspace` is read as the namespace (#918): `gpp.version = { path = "…" }` + declares the package `gpp.version`. A table was taken as one dependency + specification when it held any of those keys, whatever their values, and was + refused for naming no source; a specification's `path`, `version` and `git` + are strings and its `workspace` a boolean, and only such a value decides it. ## [2026.11.10.1] - 2026-11-10 From c81145243739736544b662b6b92141e606e72447 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Wed, 11 Nov 2026 00:16:09 +0900 Subject: [PATCH 08/13] README: the FreeBSD musl rows are preview --- README.md | 3 ++- README.zh-CN.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5576cad8b..466fd4e08 100644 --- a/README.md +++ b/README.md @@ -456,7 +456,8 @@ list` reports for this machine): | `aarch64-linux-gnu` | `llvm@23.1.3` | preview | | `aarch64-windows-gnu` | llvm 23 with `xim:mingw-w64-sysroot` (llvm-mingw's target side) — built on any host; the same base serves `x86_64-windows-gnu` where no gcc payload exists | preview | | `x86_64-freebsd` · `aarch64-freebsd` | the platform that serves them, over `xim:-freebsd-sysroot` ([22](docs/22-target-side.md)) | preview | -| `riscv64-linux-musl` · `x86_64-macos` · `x86_64-freebsd-musl` · `aarch64-freebsd-musl` · `i686-linux-musl` · `i686-linux-gnu` · `i686-openkal` | — | planned | +| `x86_64-freebsd-musl` · `aarch64-freebsd-musl` | llvm 23 — a static FreeBSD program with a musl C library over openkal-freebsd, built on any host *(what `-freebsd` is with no platform chosen)* | preview | +| `riscv64-linux-musl` · `x86_64-macos` · `i686-linux-musl` · `i686-linux-gnu` · `i686-openkal` | — | planned | | `x86_64-openkal` · `aarch64-openkal` | llvm 23 — an ok image: one artifact per architecture, run by `okrun` on Linux, macOS and Windows; the C library and C++ run-time inside it are packages ([24](docs/24-openkal-cross.md)) | verified | | `wasm32-emscripten` | `emsdk@6.0.9` — Emscripten ships its own sysroot and its own libc++ module surface; `mcpp run` executes the module with the `node` the payload declares (`xim:node`), not one found on PATH | verified | | `x86_64-linux-android` | `android-ndk@30.0.16248370` — bionic from the NDK, one payload for both ABIs; ran on an API 24 x86_64 emulator image | verified | diff --git a/README.zh-CN.md b/README.zh-CN.md index f4a1cfa29..cb61423a5 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -405,7 +405,8 @@ mcpp 的身份模型有两条正交的轴:**工具链**是 `family@version`( | `aarch64-linux-gnu` | `llvm@23.1.3` | preview | | `aarch64-windows-gnu` | llvm 23 加 `xim:mingw-w64-sysroot`(llvm-mingw 的目标侧);任意宿主可构建;没有 gcc 载荷之处同一基座也服务 `x86_64-windows-gnu` | preview | | `x86_64-freebsd` · `aarch64-freebsd` | 服务它们的平台,基于 `xim:-freebsd-sysroot`([22](docs/zh/22-target-side.md)) | preview | -| `riscv64-linux-musl` · `x86_64-macos` · `x86_64-freebsd-musl` · `aarch64-freebsd-musl` · `i686-linux-musl` · `i686-linux-gnu` · `i686-openkal` | — | planned | +| `x86_64-freebsd-musl` · `aarch64-freebsd-musl` | llvm 23;openkal-freebsd 之上带 musl C 库的静态 FreeBSD 程序,任意宿主可构建 *(未选平台时 `-freebsd` 即此身份)* | preview | +| `riscv64-linux-musl` · `x86_64-macos` · `i686-linux-musl` · `i686-linux-gnu` · `i686-openkal` | — | planned | | `x86_64-openkal` · `aarch64-openkal` | llvm 23;ok 映像:每种架构一个产物,由 `okrun` 在 Linux、macOS 与 Windows 上运行;映像内的 C 库与 C++ 运行时是包([24](docs/zh/24-openkal-cross.md)) | verified | | `wasm32-emscripten` | `emsdk@6.0.9`;Emscripten 自带 sysroot 与 libc++ 模块接口;`mcpp run` 使用 payload 声明的 `node`(`xim:node`)运行模块,不使用 PATH 上的 `node` | verified | | `x86_64-linux-android` | `android-ndk@30.0.16248370`;bionic 来自 NDK,一个 payload 服务两个 ABI;已在 API 24 的 x86_64 模拟器镜像上运行 | verified | From f9bc80fbb07ef8799bde335b39f897c2061df8d5 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Wed, 11 Nov 2026 01:36:17 +0900 Subject: [PATCH 09/13] Matrix: the FreeBSD musl rows and the 0.26.0 version group The FreeBSD musl rows build with llvm in the payload mode on every host, gcc and msvc are capability-pin, and the graph mode is platform-version-group; the openkal column is openkal-llvm-runtime 0.20.1. The linux-x86_64 cells are a scan.sh measurement. --- tests/matrix/expected.tsv | 106 ++++++++++++++++++++------------------ 1 file changed, 56 insertions(+), 50 deletions(-) diff --git a/tests/matrix/expected.tsv b/tests/matrix/expected.tsv index 8b0671150..1365e5843 100644 --- a/tests/matrix/expected.tsv +++ b/tests/matrix/expected.tsv @@ -84,11 +84,17 @@ # (`'cstdio' file not found`),是没有 cfg 的 Windows llvm 载荷不陈述配对的 # sysroot 的缺陷,修正后建出。 # +# 2026.11.10.2 改变的格(设计 2026-11-10 K9): +# - `x86_64-freebsd-musl`、`aarch64-freebsd-musl` 由 openkal-platform 0.26.0 的 hosted 部分服务 +# (openkal-freebsd standalone 之上的 openkal-musl 0.29.2):payload 体系以 llvm 建出;gcc 与 msvc +# 是 `capability-pin`;graph 体系里图中钉的版本在平台版本组之外,`platform-version-group`。 +# - openkal 各行的平台为 openkal-platform 0.26.0,openkal 列为 openkal-llvm-runtime@0.20.1。 +# # 中间五列是报告器输出,不参与支持判定。现有报告器把 aarch64-ios 的 # c-abi 输出为 glibc(payload),这不代表 iOS 产物实际链接 glibc。Apple # 目标的实际依赖由目标构建与运行门检查,不能从该报告字段推导。 -graph linux-aarch64 aarch64-freebsd-musl gcc@16.1.0 - - - - - unsupported tier-planned -graph linux-aarch64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +graph linux-aarch64 aarch64-freebsd-musl gcc@16.1.0 - - - - - unsupported capability-pin +graph linux-aarch64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported platform-version-group graph linux-aarch64 aarch64-linux-android gcc@16.1.0 - - - - - unsupported capability-pin graph linux-aarch64 aarch64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin graph linux-aarch64 aarch64-linux-gnu gcc@16.1.0 - - - - - unsupported layer-requirement @@ -109,8 +115,8 @@ graph linux-aarch64 riscv64-linux-musl gcc@16.1.0 - - - - - unsupported tier-pla graph linux-aarch64 riscv64-linux-musl llvm@23.1.3 - - - - - unsupported tier-planned graph linux-aarch64 wasm32-emscripten gcc@16.1.0 - - - - - unsupported capability-pin graph linux-aarch64 wasm32-emscripten llvm@23.1.3 - - - - - unsupported capability-pin -graph linux-aarch64 x86_64-freebsd-musl gcc@16.1.0 - - - - - unsupported tier-planned -graph linux-aarch64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +graph linux-aarch64 x86_64-freebsd-musl gcc@16.1.0 - - - - - unsupported capability-pin +graph linux-aarch64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported platform-version-group graph linux-aarch64 x86_64-linux-android gcc@16.1.0 - - - - - unsupported capability-pin graph linux-aarch64 x86_64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin graph linux-aarch64 x86_64-linux-musl gcc@16.1.0 - - - - - unsupported host-cannot-serve @@ -123,8 +129,8 @@ graph linux-aarch64 x86_64-windows-gnu gcc@16.1.0 - - - - - unsupported host-can graph linux-aarch64 x86_64-windows-gnu llvm@23.1.3 x86_64-w64-windows-gnu none musl(graph) libc++(graph) openkal-llvm-runtime@0.1.3 ok none graph linux-aarch64 x86_64-windows-musl gcc@16.1.0 - - - - - unsupported capability-pin graph linux-aarch64 x86_64-windows-musl llvm@23.1.3 - - - - - unsupported platform-version-group -graph linux-x86_64 aarch64-freebsd-musl gcc@16.1.0 - - - - - unsupported tier-planned -graph linux-x86_64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +graph linux-x86_64 aarch64-freebsd-musl gcc@16.1.0 - - - - - unsupported capability-pin +graph linux-x86_64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported platform-version-group graph linux-x86_64 aarch64-linux-android gcc@16.1.0 - - - - - unsupported capability-pin graph linux-x86_64 aarch64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin graph linux-x86_64 aarch64-linux-gnu gcc@16.1.0 - - - - - unsupported layer-requirement @@ -145,8 +151,8 @@ graph linux-x86_64 riscv64-linux-musl gcc@16.1.0 - - - - - unsupported tier-plan graph linux-x86_64 riscv64-linux-musl llvm@23.1.3 - - - - - unsupported tier-planned graph linux-x86_64 wasm32-emscripten gcc@16.1.0 - - - - - unsupported capability-pin graph linux-x86_64 wasm32-emscripten llvm@23.1.3 - - - - - unsupported capability-pin -graph linux-x86_64 x86_64-freebsd-musl gcc@16.1.0 - - - - - unsupported tier-planned -graph linux-x86_64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +graph linux-x86_64 x86_64-freebsd-musl gcc@16.1.0 - - - - - unsupported capability-pin +graph linux-x86_64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported platform-version-group graph linux-x86_64 x86_64-linux-android gcc@16.1.0 - - - - - unsupported capability-pin graph linux-x86_64 x86_64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin graph linux-x86_64 x86_64-linux-gnu gcc@16.1.0 - - - - - unsupported layer-requirement @@ -161,7 +167,7 @@ graph linux-x86_64 x86_64-windows-gnu gcc@16.1.0 - - - - - unsupported layer-req graph linux-x86_64 x86_64-windows-gnu llvm@23.1.3 x86_64-w64-windows-gnu none musl(graph) libc++(graph) openkal-llvm-runtime@0.1.3 ok none graph linux-x86_64 x86_64-windows-musl gcc@16.1.0 - - - - - unsupported capability-pin graph linux-x86_64 x86_64-windows-musl llvm@23.1.3 - - - - - unsupported platform-version-group -graph macos-arm64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +graph macos-arm64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported platform-version-group graph macos-arm64 aarch64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin graph macos-arm64 aarch64-linux-gnu llvm@23.1.3 aarch64-unknown-linux-gnu host musl(graph) libc++(graph) openkal-llvm-runtime@0.1.3 ok none graph macos-arm64 aarch64-linux-musl llvm@23.1.3 - - - - - unsupported platform-version-group @@ -174,7 +180,7 @@ graph macos-arm64 i686-linux-musl llvm@23.1.3 - - - - - unsupported tier-planned graph macos-arm64 i686-openkal llvm@23.1.3 - - - - - unsupported tier-planned graph macos-arm64 riscv64-linux-musl llvm@23.1.3 - - - - - unsupported tier-planned graph macos-arm64 wasm32-emscripten llvm@23.1.3 - - - - - unsupported capability-pin -graph macos-arm64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +graph macos-arm64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported platform-version-group graph macos-arm64 x86_64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin graph macos-arm64 x86_64-linux-musl llvm@23.1.3 - - - - - unsupported platform-version-group graph macos-arm64 x86_64-macos llvm@23.1.3 - - - - - unsupported platform-version-group @@ -182,8 +188,8 @@ graph macos-arm64 x86_64-macos-musl llvm@23.1.3 - - - - - unsupported platform-v graph macos-arm64 x86_64-openkal llvm@23.1.3 - - - - - unsupported platform-version-group graph macos-arm64 x86_64-windows-gnu llvm@23.1.3 x86_64-w64-windows-gnu none musl(graph) libc++(graph) openkal-llvm-runtime@0.1.3 ok none graph macos-arm64 x86_64-windows-musl llvm@23.1.3 - - - - - unsupported platform-version-group -graph windows-x86_64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned -graph windows-x86_64 aarch64-freebsd-musl msvc@system - - - - - unsupported tier-planned +graph windows-x86_64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported platform-version-group +graph windows-x86_64 aarch64-freebsd-musl msvc@system - - - - - unsupported capability-pin graph windows-x86_64 aarch64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin graph windows-x86_64 aarch64-linux-android msvc@system - - - - - unsupported capability-pin graph windows-x86_64 aarch64-linux-gnu llvm@23.1.3 aarch64-unknown-linux-gnu none musl(graph) libc++(graph) openkal-llvm-runtime@0.1.3 ok none @@ -204,8 +210,8 @@ graph windows-x86_64 riscv64-linux-musl llvm@23.1.3 - - - - - unsupported tier-p graph windows-x86_64 riscv64-linux-musl msvc@system - - - - - unsupported tier-planned graph windows-x86_64 wasm32-emscripten llvm@23.1.3 - - - - - unsupported capability-pin graph windows-x86_64 wasm32-emscripten msvc@system - - - - - unsupported capability-pin -graph windows-x86_64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned -graph windows-x86_64 x86_64-freebsd-musl msvc@system - - - - - unsupported tier-planned +graph windows-x86_64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported platform-version-group +graph windows-x86_64 x86_64-freebsd-musl msvc@system - - - - - unsupported capability-pin graph windows-x86_64 x86_64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin graph windows-x86_64 x86_64-linux-android msvc@system - - - - - unsupported capability-pin graph windows-x86_64 x86_64-linux-musl llvm@23.1.3 x86_64-unknown-linux-musl none musl(graph) libc++(graph) openkal-llvm-runtime@0.1.3 ok none @@ -220,8 +226,8 @@ graph windows-x86_64 x86_64-windows-msvc llvm@23.1.3 - - - - - unsupported std-m graph windows-x86_64 x86_64-windows-msvc msvc@system - - - - - unsupported host-tool-toolchain graph windows-x86_64 x86_64-windows-musl llvm@23.1.3 - - - - - unsupported platform-version-group graph windows-x86_64 x86_64-windows-musl msvc@system - - - - - unsupported capability-pin -payload linux-aarch64 aarch64-freebsd-musl gcc@16.1.0 - - - - - unsupported tier-planned -payload linux-aarch64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +payload linux-aarch64 aarch64-freebsd-musl gcc@16.1.0 - - - - - unsupported capability-pin +payload linux-aarch64 aarch64-freebsd-musl llvm@23.1.3 aarch64-unknown-freebsd14.0 payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-aarch64 aarch64-linux-android gcc@16.1.0 - - - - - unsupported capability-pin payload linux-aarch64 aarch64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin payload linux-aarch64 aarch64-linux-gnu gcc@16.1.0 - - - - - unsupported convention-unreplaced @@ -231,7 +237,7 @@ payload linux-aarch64 aarch64-linux-musl llvm@23.1.3 - - - - - unsupported conve payload linux-aarch64 aarch64-none-elf gcc@16.1.0 - - - - - unsupported capability-pin payload linux-aarch64 aarch64-none-elf llvm@23.1.3 aarch64-none-elf payload - - - ok none payload linux-aarch64 aarch64-openkal gcc@16.1.0 - - - - - unsupported capability-pin -payload linux-aarch64 aarch64-openkal llvm@23.1.3 aarch64-unknown-none-elf payload musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload linux-aarch64 aarch64-openkal llvm@23.1.3 aarch64-unknown-none-elf payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-aarch64 aarch64-windows-gnu gcc@16.1.0 - - - - - unsupported capability-pin payload linux-aarch64 aarch64-windows-gnu llvm@23.1.3 aarch64-w64-windows-gnu none ucrt(prebuilt) libc++(prebuilt) - ok none payload linux-aarch64 armv7a-none-eabi gcc@16.1.0 - - - - - unsupported capability-pin @@ -268,24 +274,24 @@ payload linux-aarch64 thumbv8m.main-none-eabihf gcc@16.1.0 - - - - - unsupported payload linux-aarch64 thumbv8m.main-none-eabihf llvm@23.1.3 thumbv8m.main-none-eabihf payload - - - ok none payload linux-aarch64 wasm32-emscripten gcc@16.1.0 - - - - - unsupported capability-pin payload linux-aarch64 wasm32-emscripten llvm@23.1.3 - - - - - unsupported capability-pin -payload linux-aarch64 x86_64-freebsd-musl gcc@16.1.0 - - - - - unsupported tier-planned -payload linux-aarch64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +payload linux-aarch64 x86_64-freebsd-musl gcc@16.1.0 - - - - - unsupported capability-pin +payload linux-aarch64 x86_64-freebsd-musl llvm@23.1.3 x86_64-unknown-freebsd14.0 payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-aarch64 x86_64-linux-android gcc@16.1.0 - - - - - unsupported capability-pin payload linux-aarch64 x86_64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin payload linux-aarch64 x86_64-linux-musl gcc@16.1.0 - - - - - unsupported host-cannot-serve -payload linux-aarch64 x86_64-linux-musl llvm@23.1.3 x86_64-unknown-linux-musl payload musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload linux-aarch64 x86_64-linux-musl llvm@23.1.3 x86_64-unknown-linux-musl payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-aarch64 x86_64-macos gcc@16.1.0 - - - - - unsupported capability-pin -payload linux-aarch64 x86_64-macos llvm@23.1.3 x86_64-apple-macos14.0 payload musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload linux-aarch64 x86_64-macos llvm@23.1.3 x86_64-apple-macos14.0 payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-aarch64 x86_64-none-elf gcc@16.1.0 - - - - - unsupported capability-pin payload linux-aarch64 x86_64-none-elf llvm@23.1.3 x86_64-none-elf payload - - - ok none payload linux-aarch64 x86_64-openkal gcc@16.1.0 - - - - - unsupported capability-pin -payload linux-aarch64 x86_64-openkal llvm@23.1.3 x86_64-unknown-none-elf payload musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload linux-aarch64 x86_64-openkal llvm@23.1.3 x86_64-unknown-none-elf payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-aarch64 x86_64-windows-gnu gcc@16.1.0 - - - - - unsupported host-cannot-serve payload linux-aarch64 x86_64-windows-gnu llvm@23.1.3 x86_64-w64-windows-gnu none ucrt(prebuilt) libc++(prebuilt) - ok none payload linux-aarch64 x86_64-windows-musl gcc@16.1.0 - - - - - unsupported capability-pin -payload linux-aarch64 x86_64-windows-musl llvm@23.1.3 x86_64-w64-windows-gnu payload musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none -payload linux-x86_64 aarch64-freebsd-musl gcc@16.1.0 - - - - - unsupported tier-planned -payload linux-x86_64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +payload linux-aarch64 x86_64-windows-musl llvm@23.1.3 x86_64-w64-windows-gnu payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none +payload linux-x86_64 aarch64-freebsd-musl gcc@16.1.0 - - - - - unsupported capability-pin +payload linux-x86_64 aarch64-freebsd-musl llvm@23.1.3 aarch64-unknown-freebsd14.0 payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-x86_64 aarch64-linux-android gcc@16.1.0 - - - - - unsupported capability-pin payload linux-x86_64 aarch64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin payload linux-x86_64 aarch64-linux-gnu gcc@16.1.0 - - - - - unsupported convention-unreplaced @@ -295,7 +301,7 @@ payload linux-x86_64 aarch64-linux-musl llvm@23.1.3 - - - - - unsupported conven payload linux-x86_64 aarch64-none-elf gcc@16.1.0 - - - - - unsupported capability-pin payload linux-x86_64 aarch64-none-elf llvm@23.1.3 aarch64-none-elf payload - - - ok none payload linux-x86_64 aarch64-openkal gcc@16.1.0 - - - - - unsupported capability-pin -payload linux-x86_64 aarch64-openkal llvm@23.1.3 aarch64-unknown-none-elf payload musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload linux-x86_64 aarch64-openkal llvm@23.1.3 aarch64-unknown-none-elf payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-x86_64 aarch64-windows-gnu gcc@16.1.0 - - - - - unsupported capability-pin payload linux-x86_64 aarch64-windows-gnu llvm@23.1.3 aarch64-w64-windows-gnu none ucrt(prebuilt) libc++(prebuilt) - ok none payload linux-x86_64 armv7a-none-eabi gcc@16.1.0 - - - - - unsupported capability-pin @@ -332,8 +338,8 @@ payload linux-x86_64 thumbv8m.main-none-eabihf gcc@16.1.0 - - - - - unsupported payload linux-x86_64 thumbv8m.main-none-eabihf llvm@23.1.3 thumbv8m.main-none-eabihf payload - - - ok none payload linux-x86_64 wasm32-emscripten gcc@16.1.0 - - - - - unsupported capability-pin payload linux-x86_64 wasm32-emscripten llvm@23.1.3 - - - - - unsupported capability-pin -payload linux-x86_64 x86_64-freebsd-musl gcc@16.1.0 - - - - - unsupported tier-planned -payload linux-x86_64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +payload linux-x86_64 x86_64-freebsd-musl gcc@16.1.0 - - - - - unsupported capability-pin +payload linux-x86_64 x86_64-freebsd-musl llvm@23.1.3 x86_64-unknown-freebsd14.0 payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-x86_64 x86_64-linux-android gcc@16.1.0 - - - - - unsupported capability-pin payload linux-x86_64 x86_64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin payload linux-x86_64 x86_64-linux-gnu gcc@16.1.0 x86_64-unknown-linux-gnu subos glibc(payload) libstdc++(payload) - ok none @@ -341,25 +347,25 @@ payload linux-x86_64 x86_64-linux-gnu llvm@23.1.3 x86_64-unknown-linux-gnu paylo payload linux-x86_64 x86_64-linux-musl gcc@16.1.0 x86_64-unknown-linux-musl payload musl(payload) libstdc++(payload) - ok none payload linux-x86_64 x86_64-linux-musl llvm@23.1.3 - - - - - unsupported convention-unreplaced payload linux-x86_64 x86_64-macos gcc@16.1.0 - - - - - unsupported capability-pin -payload linux-x86_64 x86_64-macos llvm@23.1.3 x86_64-apple-macos14.0 payload musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload linux-x86_64 x86_64-macos llvm@23.1.3 x86_64-apple-macos14.0 payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-x86_64 x86_64-none-elf gcc@16.1.0 - - - - - unsupported capability-pin payload linux-x86_64 x86_64-none-elf llvm@23.1.3 x86_64-none-elf payload - - - ok none payload linux-x86_64 x86_64-openkal gcc@16.1.0 - - - - - unsupported capability-pin -payload linux-x86_64 x86_64-openkal llvm@23.1.3 x86_64-unknown-none-elf payload musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload linux-x86_64 x86_64-openkal llvm@23.1.3 x86_64-unknown-none-elf payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload linux-x86_64 x86_64-windows-gnu gcc@16.1.0 x86_64-w64-windows-gnu none ucrt(payload) libstdc++(payload) - ok none payload linux-x86_64 x86_64-windows-gnu llvm@23.1.3 x86_64-w64-windows-gnu none ucrt(payload) libstdc++(payload) - ok none payload linux-x86_64 x86_64-windows-musl gcc@16.1.0 - - - - - unsupported capability-pin -payload linux-x86_64 x86_64-windows-musl llvm@23.1.3 x86_64-w64-windows-gnu payload musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none -payload macos-arm64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +payload linux-x86_64 x86_64-windows-musl llvm@23.1.3 x86_64-w64-windows-gnu payload musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none +payload macos-arm64 aarch64-freebsd-musl llvm@23.1.3 aarch64-unknown-freebsd14.0 host musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload macos-arm64 aarch64-ios llvm@23.1.3 arm64-apple-ios18.5 host glibc(payload) libc++(payload) - ok none payload macos-arm64 aarch64-ios-sim llvm@23.1.3 arm64-apple-ios18.5-simulator host sim(payload) libc++(payload) - ok none payload macos-arm64 aarch64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin payload macos-arm64 aarch64-linux-gnu llvm@23.1.3 - - - - - unsupported host-cannot-serve -payload macos-arm64 aarch64-linux-musl llvm@23.1.3 aarch64-unknown-linux-musl host musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload macos-arm64 aarch64-linux-musl llvm@23.1.3 aarch64-unknown-linux-musl host musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload macos-arm64 aarch64-macos llvm@23.1.3 arm64-apple-macos14.0 host libSystem(payload) libc++(payload) - ok none -payload macos-arm64 aarch64-macos-musl llvm@23.1.3 arm64-apple-macos14.0 host musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload macos-arm64 aarch64-macos-musl llvm@23.1.3 arm64-apple-macos14.0 host musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload macos-arm64 aarch64-none-elf llvm@23.1.3 aarch64-none-elf host - - - ok none -payload macos-arm64 aarch64-openkal llvm@23.1.3 aarch64-unknown-none-elf host musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload macos-arm64 aarch64-openkal llvm@23.1.3 aarch64-unknown-none-elf host musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload macos-arm64 aarch64-windows-gnu llvm@23.1.3 aarch64-w64-windows-gnu none ucrt(prebuilt) libc++(prebuilt) - ok none payload macos-arm64 armv7a-none-eabi llvm@23.1.3 armv7a-none-eabi host - - - ok none payload macos-arm64 armv7a-none-eabihf llvm@23.1.3 armv7a-none-eabihf host - - - ok none @@ -378,27 +384,27 @@ payload macos-arm64 thumbv8m.base-none-eabi llvm@23.1.3 thumbv8m.base-none-eabi payload macos-arm64 thumbv8m.main-none-eabi llvm@23.1.3 thumbv8m.main-none-eabi host - - - ok none payload macos-arm64 thumbv8m.main-none-eabihf llvm@23.1.3 thumbv8m.main-none-eabihf host - - - ok none payload macos-arm64 wasm32-emscripten llvm@23.1.3 - - - - - unsupported capability-pin -payload macos-arm64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned +payload macos-arm64 x86_64-freebsd-musl llvm@23.1.3 x86_64-unknown-freebsd14.0 host musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload macos-arm64 x86_64-ios-sim llvm@23.1.3 x86_64-apple-ios18.5-simulator host sim(payload) libc++(payload) - ok none payload macos-arm64 x86_64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin -payload macos-arm64 x86_64-linux-musl llvm@23.1.3 x86_64-unknown-linux-musl host musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none -payload macos-arm64 x86_64-macos llvm@23.1.3 x86_64-apple-macos14.0 host musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none -payload macos-arm64 x86_64-macos-musl llvm@23.1.3 x86_64-apple-macos14.0 host musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload macos-arm64 x86_64-linux-musl llvm@23.1.3 x86_64-unknown-linux-musl host musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none +payload macos-arm64 x86_64-macos llvm@23.1.3 x86_64-apple-macos14.0 host musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none +payload macos-arm64 x86_64-macos-musl llvm@23.1.3 x86_64-apple-macos14.0 host musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload macos-arm64 x86_64-none-elf llvm@23.1.3 x86_64-none-elf host - - - ok none -payload macos-arm64 x86_64-openkal llvm@23.1.3 x86_64-unknown-none-elf host musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload macos-arm64 x86_64-openkal llvm@23.1.3 x86_64-unknown-none-elf host musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload macos-arm64 x86_64-windows-gnu llvm@23.1.3 x86_64-w64-windows-gnu none ucrt(prebuilt) libc++(prebuilt) - ok none -payload macos-arm64 x86_64-windows-musl llvm@23.1.3 x86_64-w64-windows-gnu host musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none -payload windows-x86_64 aarch64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned -payload windows-x86_64 aarch64-freebsd-musl msvc@system - - - - - unsupported tier-planned +payload macos-arm64 x86_64-windows-musl llvm@23.1.3 x86_64-w64-windows-gnu host musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none +payload windows-x86_64 aarch64-freebsd-musl llvm@23.1.3 aarch64-unknown-freebsd14.0 none musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none +payload windows-x86_64 aarch64-freebsd-musl msvc@system - - - - - unsupported capability-pin payload windows-x86_64 aarch64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin payload windows-x86_64 aarch64-linux-android msvc@system - - - - - unsupported capability-pin payload windows-x86_64 aarch64-linux-gnu llvm@23.1.3 - - - - - unsupported host-cannot-serve payload windows-x86_64 aarch64-linux-gnu msvc@system - - - - - unsupported convention-unreplaced -payload windows-x86_64 aarch64-linux-musl llvm@23.1.3 aarch64-unknown-linux-musl none musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload windows-x86_64 aarch64-linux-musl llvm@23.1.3 aarch64-unknown-linux-musl none musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload windows-x86_64 aarch64-linux-musl msvc@system - - - - - unsupported convention-unreplaced payload windows-x86_64 aarch64-none-elf llvm@23.1.3 aarch64-none-elf none - - - ok none payload windows-x86_64 aarch64-none-elf msvc@system - - - - - unsupported capability-pin -payload windows-x86_64 aarch64-openkal llvm@23.1.3 aarch64-unknown-none-elf none musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload windows-x86_64 aarch64-openkal llvm@23.1.3 aarch64-unknown-none-elf none musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload windows-x86_64 aarch64-openkal msvc@system - - - - - unsupported capability-pin payload windows-x86_64 aarch64-windows-gnu llvm@23.1.3 aarch64-w64-windows-gnu none ucrt(prebuilt) libc++(prebuilt) - ok none payload windows-x86_64 aarch64-windows-gnu msvc@system - - - - - unsupported capability-pin @@ -436,21 +442,21 @@ payload windows-x86_64 thumbv8m.main-none-eabihf llvm@23.1.3 thumbv8m.main-none- payload windows-x86_64 thumbv8m.main-none-eabihf msvc@system - - - - - unsupported capability-pin payload windows-x86_64 wasm32-emscripten llvm@23.1.3 - - - - - unsupported capability-pin payload windows-x86_64 wasm32-emscripten msvc@system - - - - - unsupported capability-pin -payload windows-x86_64 x86_64-freebsd-musl llvm@23.1.3 - - - - - unsupported tier-planned -payload windows-x86_64 x86_64-freebsd-musl msvc@system - - - - - unsupported tier-planned +payload windows-x86_64 x86_64-freebsd-musl llvm@23.1.3 x86_64-unknown-freebsd14.0 none musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none +payload windows-x86_64 x86_64-freebsd-musl msvc@system - - - - - unsupported capability-pin payload windows-x86_64 x86_64-linux-android llvm@23.1.3 - - - - - unsupported capability-pin payload windows-x86_64 x86_64-linux-android msvc@system - - - - - unsupported capability-pin payload windows-x86_64 x86_64-linux-musl llvm@23.1.3 - - - - - unsupported convention-unreplaced payload windows-x86_64 x86_64-linux-musl msvc@system - - - - - unsupported convention-unreplaced -payload windows-x86_64 x86_64-macos llvm@23.1.3 x86_64-apple-macos14.0 none musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload windows-x86_64 x86_64-macos llvm@23.1.3 x86_64-apple-macos14.0 none musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload windows-x86_64 x86_64-macos msvc@system - - - - - unsupported capability-pin payload windows-x86_64 x86_64-none-elf llvm@23.1.3 - - - - - unsupported lld-required-absent payload windows-x86_64 x86_64-none-elf msvc@system - - - - - unsupported capability-pin -payload windows-x86_64 x86_64-openkal llvm@23.1.3 x86_64-unknown-none-elf none musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload windows-x86_64 x86_64-openkal llvm@23.1.3 x86_64-unknown-none-elf none musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload windows-x86_64 x86_64-openkal msvc@system - - - - - unsupported capability-pin payload windows-x86_64 x86_64-windows-gnu llvm@23.1.3 x86_64-w64-windows-gnu none ucrt(payload) libstdc++(payload) - ok none payload windows-x86_64 x86_64-windows-gnu msvc@system - - - - - unsupported convention-unreplaced payload windows-x86_64 x86_64-windows-msvc llvm@23.1.3 x86_64-pc-windows-msvc none msvc(payload) msvc-stl(payload) - ok none payload windows-x86_64 x86_64-windows-msvc msvc@system x86_64-pc-windows-msvc none msvc(payload) (payload) - ok none -payload windows-x86_64 x86_64-windows-musl llvm@23.1.3 x86_64-w64-windows-gnu none musl(platform) libc++(platform) openkal-llvm-runtime@0.19.2 ok none +payload windows-x86_64 x86_64-windows-musl llvm@23.1.3 x86_64-w64-windows-gnu none musl(platform) libc++(platform) openkal-llvm-runtime@0.20.1 ok none payload windows-x86_64 x86_64-windows-musl msvc@system - - - - - unsupported capability-pin From 8766d24d661395dc6063812f3a0ec842f1cc6a2d Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Wed, 11 Nov 2026 01:45:29 +0900 Subject: [PATCH 10/13] A platform refused for a row names the rows its providers serve The refusal listed only the platform's targets, and was empty for a platform that states [[platform.provider]]. e2e 1059 asserts the refusal of x86_64-freebsd-musl by a platform chosen with cfg(os = "freebsd"). --- CHANGELOG.md | 3 +++ src/platform/platform.cppm | 16 ++++++++++++---- ...age_states_the_layers_beside_its_c_library.sh | 4 ++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 315ecaa4c..6b1963f40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,9 @@ specification when it held any of those keys, whatever their values, and was refused for naming no source; a specification's `path`, `version` and `git` are strings and its `workspace` a boolean, and only such a value decides it. +- A platform refused for a row it does not serve names the rows its providers + serve; the list named only its `targets` and was empty for a platform that + states `[[platform.provider]]`. ## [2026.11.10.1] - 2026-11-10 diff --git a/src/platform/platform.cppm b/src/platform/platform.cppm index 9976a6395..024641ff9 100644 --- a/src/platform/platform.cppm +++ b/src/platform/platform.cppm @@ -459,8 +459,16 @@ serves(const mp::Statement& p, std::string_view package, const mcpp::toolchain:: auto pt = mcpp::toolchain::triple::parse(w); if (pt ? pt->str() == t.str() : w == t.str()) return false; } - std::string list; - for (auto const& w : p.targets.value) { if (!list.empty()) list += ", "; list += w; } + // What it serves: its targets and the identities its providers name. + std::string list, first; + auto name = [&](std::string_view w) { + if (first.empty()) first = std::string(w); + if (!list.empty()) list += ", "; + list += w; + }; + for (auto const& w : p.targets.value) name(w); + for (auto const& pr : p.providers) + for (auto const& w : pr.serves) name(w); if (p.hosted.set) { if (!p.hosted.targets.set) return true; std::string hosts; @@ -495,8 +503,8 @@ serves(const mp::Statement& p, std::string_view package, const mcpp::toolchain:: "platform {} serves {} and not {}: it has no [platform.hosted] table, the part a host " "triple may take (SPEC-013 §5.4).\n" " Build for one of its targets (--target {}), or select another platform for {}", - package, list, t.str(), p.targets.value.empty() ? std::string("") : p.targets.value.front(), - t.str())); + package, list.empty() ? std::string("nothing") : list, t.str(), + first.empty() ? std::string("") : first, t.str())); } TargetFlags evaluate_flags(const mp::Statement& s, const Matches& matches) { diff --git a/tests/e2e/1059_a_base_package_states_the_layers_beside_its_c_library.sh b/tests/e2e/1059_a_base_package_states_the_layers_beside_its_c_library.sh index ff4304be7..b05206aef 100755 --- a/tests/e2e/1059_a_base_package_states_the_layers_beside_its_c_library.sh +++ b/tests/e2e/1059_a_base_package_states_the_layers_beside_its_c_library.sh @@ -95,4 +95,8 @@ out=$("$MCPP" why flags --target aarch64-freebsd 2>&1) || fail "the aarch64 plan grep -q -- "--sysroot=$t/aarch64-toy-sysroot" <<<"$out" || fail "aarch64 does not take its own base" "$out" grep -qE 'c\+\+-abi +libc\+\+ +\(aarch64-toy-sysroot@1.0, prebuilt' <<<"$out" || fail "aarch64's C++ layer is not its base's" "$out" echo " ok each identity takes the base its provider names" +out=$("$MCPP" why flags --target x86_64-freebsd-musl 2>&1) && fail "the musl row was served by a platform that does not serve it" "$out" +grep -q 'serves x86_64-freebsd, aarch64-freebsd and not x86_64-freebsd-musl' <<<"$out" \ + || fail "the refusal does not name what the platform serves" "$out" +echo " ok a row the chosen platform does not serve is refused, naming the rows it serves" echo "PASS: 1059 a base package states the layers beside its C library" From 3c296814c51ceade13f2ac526804537ce3ca2279 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Wed, 11 Nov 2026 01:48:44 +0900 Subject: [PATCH 11/13] prepare_inputs: the bareword vocabulary precedes the comment of unknown_tokens --- src/build/prepare_inputs.cppm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/build/prepare_inputs.cppm b/src/build/prepare_inputs.cppm index 6049aa73f..845f71991 100644 --- a/src/build/prepare_inputs.cppm +++ b/src/build/prepare_inputs.cppm @@ -471,10 +471,6 @@ inline bool uses_layer(const std::string& predicate) { [](auto const& k) { return is_cfg_late_layer_key(k); }); } -// Tokens outside the vocabulary. A predicate naming one of these used to -// evaluate to false in silence, which is indistinguishable from a predicate -// that correctly did not apply — so `[target.'cfg(c-abi = "musl")'.build]` was -// dropped without a word for the entire time docs/14 documented it. // The systems the rows name (built-in and defined), and the family word. inline std::vector system_barewords() { std::set systems; @@ -489,6 +485,10 @@ inline bool known_bareword(std::string_view w) { return std::ranges::any_of(mcpp::toolchain::target::rows(), [&](auto const* r) { return r->os == w; }); } +// Tokens outside the vocabulary. A predicate naming one of these used to +// evaluate to false in silence, which is indistinguishable from a predicate +// that correctly did not apply — so `[target.'cfg(c-abi = "musl")'.build]` was +// dropped without a word for the entire time docs/14 documented it. inline std::vector unknown_tokens(const std::string& predicate) { auto scan = scan_predicate(predicate); std::vector out; From fe43d66ada05290e7246946dd50f8a4ca525c9fe Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Wed, 11 Nov 2026 02:13:24 +0900 Subject: [PATCH 12/13] test: a test of an unchanged project that this host cannot execute names the host's target --- CHANGELOG.md | 3 +++ src/build/execute.cppm | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b1963f40..40fde30df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,9 @@ - A platform refused for a row it does not serve names the rows its providers serve; the list named only its `targets` and was empty for a platform that states `[[platform.provider]]`. +- A test of an unchanged project that this host cannot execute is reported for + the host's target: `mcpp test` without planning (2026.11.10.1) named an empty + target in the refusal and in the `[target.…].runner` it proposes. ## [2026.11.10.1] - 2026-11-10 diff --git a/src/build/execute.cppm b/src/build/execute.cppm index f2302f28c..ad4cb0065 100644 --- a/src/build/execute.cppm +++ b/src/build/execute.cppm @@ -6346,6 +6346,9 @@ export int run_tests(std::span passthrough, if (auto runs = fast_test_plan(testRoot, testOpts, names, passthrough, programEnv, fastCtx)) { TestBuild tb; tb.ctx.emplace(std::move(fastCtx)); + // The record serves the host only and no runner: the target a + // refusal to execute names is the host's. + tb.runnerChoice.tripleKey = legTriple; tb.archived = std::move(*runs); tb.bulkBuiltEverything = true; tb.programEnv = programEnv; From 1444aaf4651d0884dcc1fedf76a45492f35e69d7 Mon Sep 17 00:00:00 2001 From: Sunrisepeak Date: Wed, 11 Nov 2026 03:57:14 +0900 Subject: [PATCH 13/13] The compiler witness asks again for a record Windows refuses; the matrix scan reports supervision lines --- CHANGELOG.md | 7 +++++ src/build/schedule/compiler_transaction.cppm | 30 +++++++++++++++----- tests/matrix/scan.sh | 5 ++-- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40fde30df..b0ca51646 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,13 @@ - A test of an unchanged project that this host cannot execute is reported for the host's target: `mcpp test` without planning (2026.11.10.1) named an empty target in the refusal and in the `[target.…].runner` it proposes. +- A compiler record that Windows refuses to a reader for longer than the + publication bound is asked for again at the witness's next audit, as an + unknown controller already was; the refusal ends the build only when it + outlasts the startup grace. It ended a Windows build with "a compiler + controller ended before completion" after a large package installation. The + target-matrix scan reports the supervision's own `mcpp:` lines with a failed + cell. ## [2026.11.10.1] - 2026-11-10 diff --git a/src/build/schedule/compiler_transaction.cppm b/src/build/schedule/compiler_transaction.cppm index 58dc457ef..471292c28 100644 --- a/src/build/schedule/compiler_transaction.cppm +++ b/src/build/schedule/compiler_transaction.cppm @@ -53,6 +53,9 @@ inline constexpr auto kRecordSettle=std::chrono::milliseconds(250); // registering its unit with the generation's owner. One bound for both, so a // registration retried within it never outlives the wait for it. inline constexpr auto kStartupGrace=std::chrono::seconds(10); +// A record that exists and is still refused after kRecordSettle. The refusal +// is a fact about the moment, not about the record's content. +inline constexpr std::string_view kRecordUnreadable="cannot read compiler transaction record"; enum class Opened { yes, absent, refused }; // Opens `path' for reading, waiting out a publication in progress. Opened open_settled(std::ifstream& input,const fs::path& path) { @@ -76,10 +79,10 @@ Record read(const fs::path& path, std::string_view tag) { std::ifstream input; const auto opened=open_settled(input,path); if(opened==Opened::absent)return std::optional{}; - if(opened==Opened::refused)return std::unexpected("cannot read compiler transaction record"); + if(opened==Opened::refused)return std::unexpected(std::string(kRecordUnreadable)); std::string bytes(65537,'\0'); input.read(bytes.data(),bytes.size());bytes.resize(static_cast(input.gcount())); - if(input.bad())return std::unexpected("cannot read compiler transaction record"); + if(input.bad())return std::unexpected(std::string(kRecordUnreadable)); if (bytes.size() < 18 || bytes.size() > 65536 || bytes[bytes.size()-18] != '\n' || bytes.back() != '\n') return std::unexpected("corrupt compiler transaction record"); const auto body = std::string_view(bytes).substr(0,bytes.size()-18); @@ -438,6 +441,18 @@ private: std::atomic stopping_{false},failed_{false}; std::mutex admission_; ObserverMap held_; + // AN UNREADABLE RECORD IS ASKED AGAIN AT THE NEXT AUDIT, as an unknown + // controller is. A Windows reader can be refused a just-published record + // for longer than kRecordSettle while the host scans new files; the + // refusal decides the loss of a compiler only when it outlasts the + // startup grace. Corrupt content is decided at once. + std::map unreadable_; + bool settling(const std::string& attempt,std::string_view error) { + if(error!=kRecordUnreadable)return false; + const auto now=std::chrono::steady_clock::now(); + const auto first=unreadable_.try_emplace(attempt,now).first->second; + return now-firstfirst); auto retired=read(directory/"retired","mcpp-retired-v1"); - if(!retired) {fail(retired.error());++it;continue;} + if(!retired) {if(!settling(it->first,retired.error()))fail(retired.error());++it;continue;} if(*retired&&(**retired).size()!=3) {fail("invalid retirement certificate");++it;continue;} - if(*retired) {it=held_.erase(it);continue;} + if(*retired) {unreadable_.erase(it->first);it=held_.erase(it);continue;} auto attempt=Attempt::load(directory); - if(!attempt) {fail(attempt.error());++it;continue;} + if(!attempt) {if(!settling(it->first,attempt.error()))fail(attempt.error());++it;continue;} + unreadable_.erase(it->first); const auto state=controller_state(*attempt); if(state==Controller::unknown) {++it;continue;} // asked again at the next audit if(state==Controller::ended) { // Retirement can be published between the first read and the // controller's exit. Observe it again before reporting loss. retired=read(directory/"retired","mcpp-retired-v1"); - if(!retired)fail(retired.error()); + if(!retired) {if(!settling(it->first,retired.error()))fail(retired.error());} else if(*retired&&(**retired).size()!=3)fail("invalid retirement certificate"); - else if(*retired) {it=held_.erase(it);continue;} + else if(*retired) {unreadable_.erase(it->first);it=held_.erase(it);continue;} else fail("controller ended without retirement certificate"); } ++it; diff --git a/tests/matrix/scan.sh b/tests/matrix/scan.sh index 2d03ad7c5..656b9e435 100755 --- a/tests/matrix/scan.sh +++ b/tests/matrix/scan.sh @@ -279,9 +279,10 @@ for tc in $(compilers); do # 这里只留错误行,不倒整份构建日志 —— 40 格 × 一份完整日志读不动。 # 三行,**整行**。前一版 `cut -c1-160` 把真正的错误砍在半路 —— # macOS 那格只留下 `precompiled file '/private/var/…/target/` 就没了, - # 而要看的正是后半截。判据的单位是一整行输出。 + # 而要看的正是后半截。判据的单位是一整行输出。`mcpp:` 行是编译器 + # 监督自身的陈述(哪一次观察判定了失败),它不带 `error:`,却是原因。 echo "scan: $t × $tc 构建失败:" >&2 - grep -m3 -iE '^error|error:' "$work/b.out" | sed 's/^/ /' >&2 + grep -m4 -iE '^error|error:|^mcpp: ' "$work/b.out" | sed 's/^/ /' >&2 emit "$MODE" "$HOST" "$t" "$tc" "$tri" "$clib" "$cabi" "$cxxabi" "$okpkg" \ mismatch build-failed fi