Skip to content

Commit d6b6906

Browse files
committed
openkal measurement selects by change and names the Windows target x86_64-windows-musl; a CN mirror may be the maintainer's own
compat.py select: a change measured every member whenever anything under tests/openkal/ moved, so adding one member cost the whole list. It now measures every member only when the graph or the harness changes (an openkal family descriptor, pins.toml, compat.py); a members.toml edit measures the entries added or changed against the merge base (--base), a member's own test project measures that member, and a descriptor measures the members that depend on it, as before. The workflow passes the merge base and now also triggers on tests/examples/**. selftest pins each rule. The Windows target is x86_64-windows-musl. The graph presents musl's C environment there, and x86_64-windows-gnu read as a mingw-w64 build, which it never was. Measured locally with the pins (mcpp 2026.9.21.3, runtime 0.15.1): cli11, zlib and cmp-module run; curl stops at the same curl_setup.h:591; yaml-cpp and yaml-cpp-v080 run. Renaming the target moves the harness, so this pull request measures every member once, and that measurement becomes the published baseline. check_mirror_urls.lua required every CN url to live under gitcode mcpp-res. A library's maintainer may host the mirror instead; the rule is now a gitcode release asset under any owner. ZheFeng7110.boost's mirror (#463), which has kept lint red on main since, passes unchanged.
1 parent 4cdf102 commit d6b6906

10 files changed

Lines changed: 196 additions & 40 deletions

File tree

‎.github/workflows/openkal-compat.yml‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ on:
2525
paths:
2626
- "pkgs/**/*.lua"
2727
- "tests/openkal/**"
28+
- "tests/examples/**"
2829
- ".xpkgindex/openkal-compat.json"
2930
- ".github/workflows/openkal-compat.yml"
3031

@@ -68,15 +69,17 @@ jobs:
6869
with:
6970
fetch-depth: 0
7071

71-
# A pull request measures the members its change can affect; the schedule
72-
# and a request with no members measure every listed member.
72+
# A pull request measures the members its change can affect (see
73+
# `select_members` in compat.py: adding one member measures that member);
74+
# the schedule and a request with no members measure every listed member.
7375
- name: Select the members
7476
id: select
7577
shell: bash
7678
run: |
7779
if [ "${{ github.event_name }}" = "pull_request" ]; then
78-
files=$(git diff --name-only "origin/${{ github.base_ref }}...HEAD")
79-
members=$(python3 tests/openkal/compat.py select $files)
80+
base=$(git merge-base "origin/${{ github.base_ref }}" HEAD)
81+
files=$(git diff --name-only "$base" HEAD)
82+
members=$(python3 tests/openkal/compat.py select --base "$base" $files)
8083
else
8184
members="${{ github.event.inputs.members }}"
8285
[ -n "$members" ] || members=$(python3 tests/openkal/compat.py select tests/openkal/)

‎CHANGELOG.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@
2323
包归入 `openkal-ecosystem`;测试项目在 openkal 依赖图中测得 `runs` 的包归入
2424
`openkal-compat`。只测得 `builds` 或 `fails` 的包不再归入分面,其页面仍按目标列出测量结果
2525
与第一条诊断。
26+
- **openkal 测量按改动选成员,不再每次全量。** `compat.py select --base <merge-base>`:
27+
改动 openkal 家族描述符、`pins.toml`、`compat.py` 才测全部成员;改 `members.toml` 只测
28+
新增或改动的条目(`[not-portable]` 计入所指成员,`[excluded]` 不选);改
29+
`tests/examples/<成员>/` 测该成员;改描述符测依赖它的成员。`selftest` 为每条规则各加一例。
30+
- **openkal 的 Windows 目标改名为 `x86_64-windows-musl`。** 依赖图在 Windows 上呈现的是
31+
musl 的 C 环境,不是 MinGW;`x86_64-windows-gnu` 会被读成 mingw-w64 构建。实测同一依赖图:
32+
cli11、zlib、cmp-module 仍 runs,curl 仍停在同一条 `curl_setup.h:591`。2026-09-23 之前的
33+
结果仍记在旧名下。
34+
- **CN 镜像可以由库的维护者自己托管。** `check_mirror_urls.lua` 要求 `CN` 是 gitcode 的
35+
release 资产(`https://gitcode.com/<owner>/<repo>/releases/download/…`),不再限定
36+
`mcpp-res` 组织;`mcpp-res` 仍是默认。#463 起 `main` 上的 lint 因 `ZheFeng7110.boost`
37+
的维护者镜像而失败,现在通过。
2638

2739
### Fixed
2840

‎docs/cn-mirror.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@ effect through the existing engine.
1414
for the `nlohmann` family prefer `nlohmann-json`, to avoid the ambiguity of a bare `json`).
1515
- The public URL of a CN asset follows this convention:
1616
`https://gitcode.com/mcpp-res/<slug>/releases/download/<ver>/<slug>-<ver>.<ext>`
17+
- A library's own maintainer may host its CN mirror instead, under their own gitcode account
18+
(`https://gitcode.com/<owner>/<repo>/releases/download/<tag>/<file>`, as `ZheFeng7110.boost` does). They then keep it
19+
in step with the GLOBAL asset: the same bytes, so the same `sha256`.
1720

1821
## Fallback without `mcpp-res` write access
1922

2023
Setting up a mirror requires write access (a token) to the gitcode `mcpp-res` organization. Without it, do not force a
2124
mirror table into existence: lint (`check_mirror_urls.lua`) mandates that once `url` is written as a table, its `CN`
22-
must be `https://gitcode.com/mcpp-res/…`, so `{ GLOBAL=upstream, CN=upstream }` fails lint outright. The correct
25+
must be a gitcode release asset (`https://gitcode.com/<owner>/<repo>/releases/download/…`), so
26+
`{ GLOBAL=upstream, CN=upstream }` fails lint outright. The correct
2327
fallback is a plain-string url (upstream release only) — lint imposes no mirror constraint on plain-string urls:
2428

2529
```lua

‎docs/openkal-compat.md‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ fails is measured and published, not excluded.
122122

123123
`[not-portable.<member>]` declares one TARGET of one member unbuildable by
124124
construction, with the reason. It exists because `[excluded]` is whole-member
125-
and some members are neither: `cmp-module` runs on `x86_64-windows-gnu` and
125+
and some members are neither: `cmp-module` runs on `x86_64-windows-musl` and
126126
cannot build on `x86_64-linux-gnu`, because asio's `detail/config.hpp`
127127
includes `<linux/version.h>` whenever `__linux__` is defined, outside every
128128
`ASIO_DISABLE_*` guard. Excluding the member outright would discard a result
@@ -148,7 +148,7 @@ Both are recipe defects, and neither is the same defect:
148148
| target | first diagnostic | cause |
149149
| --- | --- | --- |
150150
| `x86_64-linux-gnu` | `lib/setopt.c:31: 'linux/tcp.h' file not found` | `#define HAVE_LINUX_TCP_H 1` inside `#if defined(__linux__)`. The kernel IS Linux, so the predicate is right; what is wrong is reading it as "glibc's userspace headers are installed". The honest test is `__has_include(<linux/tcp.h>)`. The same block also asserts `HAVE_GLIBC_STRERROR_R`, which is false over musl. |
151-
| `x86_64-windows-gnu` | `curl_setup.h:591: "too small curl_off_t"` | The recipe's `windows` branch omits `HAVE_CONFIG_H` so that `curl_setup.h` reaches the checked-in `lib/config-win32.h`, and links `-lws2_32` with Schannel. Over openkal that target presents POSIX and is **LP64**, while `config-win32.h` is written for LLP64 and the Win32 API. |
151+
| `x86_64-windows-musl` | `curl_setup.h:591: "too small curl_off_t"` | The recipe's `windows` branch omits `HAVE_CONFIG_H` so that `curl_setup.h` reaches the checked-in `lib/config-win32.h`, and links `-lws2_32` with Schannel. Over openkal that target presents POSIX and is **LP64**, while `config-win32.h` is written for LLP64 and the Win32 API. |
152152

153153
**The second is the interesting one: the recipe branches on the PLATFORM where
154154
the question is about the C ENVIRONMENT.** Those two agreed on every target
@@ -162,10 +162,23 @@ it is a larger change than the first and is not folded into it.
162162
## 3. When it runs
163163

164164
`.github/workflows/openkal-compat.yml` runs weekly and on demand, measuring every
165-
listed member. For a pull request it measures every member when the openkal
166-
family or `tests/openkal` changes, and otherwise the members whose test projects
167-
depend on a changed descriptor. It does not block a merge unless the comparison
168-
below is enabled.
165+
listed member. For a pull request, `compat.py select` measures only what the
166+
change can affect:
167+
168+
| The pull request changes | Members measured |
169+
| --- | --- |
170+
| an openkal family descriptor, `pins.toml`, `compat.py`, or anything else under `tests/openkal/` except `members.toml` | every listed member: the graph or the harness changed |
171+
| `members.toml` | the members whose entry was added or changed, compared with the base branch; a `[not-portable]` declaration counts for the member it names, and `[excluded]` selects nothing |
172+
| `tests/examples/<member>/` | that member, if it is listed |
173+
| a descriptor under `pkgs/` | the listed members whose test projects depend on it |
174+
175+
Adding a member therefore measures that member, not the whole list. The
176+
workflow does not block a merge unless the comparison below is enabled.
177+
178+
The targets are `x86_64-linux-gnu` and `x86_64-windows-musl`. The Windows
179+
target is named for the C environment the graph presents there, which is
180+
musl's, not MinGW's. Results measured before 2026-09-23 are recorded as
181+
`x86_64-windows-gnu`, the name that target had then.
169182

170183
It installs the Windows cross toolchain's host headers on purpose. A build that
171184
reached the host's headers would change its result when they are present, so a

‎docs/zh/cn-mirror.md‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,15 @@
1212
`nlohmann-json` 以避免裸 `json` 的歧义)。
1313
- CN 资产的公网 URL 约定为:
1414
`https://gitcode.com/mcpp-res/<slug>/releases/download/<ver>/<slug>-<ver>.<ext>`
15+
- 库的维护者也可以在自己的 gitcode 账号下自行维护 CN 镜像
16+
(`https://gitcode.com/<owner>/<repo>/releases/download/<tag>/<file>`,如 `ZheFeng7110.boost`)。
17+
此时由维护者保证它与 GLOBAL 资产字节一致,即 `sha256` 相同。
1518

1619
## 无 `mcpp-res` 写权限时的回退
1720

1821
建立镜像需要 gitcode `mcpp-res` 组织的写权限(token)。在不具备该权限时,不应勉强构造镜像表:lint
19-
(`check_mirror_urls.lua`)强制要求,一旦 `url` 写成表形式,其 `CN` 必须为 `https://gitcode.com/mcpp-res/…`,
22+
(`check_mirror_urls.lua`)强制要求,一旦 `url` 写成表形式,其 `CN` 必须为 gitcode 的 release 资产
23+
(`https://gitcode.com/<owner>/<repo>/releases/download/…`),
2024
因此 `{ GLOBAL=上游, CN=上游 }` 会直接导致 lint 失败。正确的回退方式是采用纯字符串 url(仅填上游 release),
2125
lint 对纯字符串 url 不施加镜像约束:
2226

‎docs/zh/openkal-compat.md‎

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
`tests/openkal/members.toml` 列出测量对象。`[excluded]` 列出在任何 openkal 依赖图中都无法构建的成员,并逐条写明原因;失败的成员照常测量并公布,不列入排除。
4444

45-
`[not-portable.<成员>]` 声明某个成员的**某一个目标**按构造无法构建,并写明理由。它存在是因为 `[excluded]` 是整成员级的,而有些成员两头都不是:`cmp-module` 在 `x86_64-windows-gnu` 上 runs,在 `x86_64-linux-gnu` 上建不起来——asio 的 `detail/config.hpp` 只要 `__linux__` 有定义就 include `<linux/version.h>`,而那行在所有 `ASIO_DISABLE_*` 守卫之外。整个排除掉这个成员,等于为了藏起一个真的结果而丢掉另一个同样真的结果。
45+
`[not-portable.<成员>]` 声明某个成员的**某一个目标**按构造无法构建,并写明理由。它存在是因为 `[excluded]` 是整成员级的,而有些成员两头都不是:`cmp-module` 在 `x86_64-windows-musl` 上 runs,在 `x86_64-linux-gnu` 上建不起来——asio 的 `detail/config.hpp` 只要 `__linux__` 有定义就 include `<linux/version.h>`,而那行在所有 `ASIO_DISABLE_*` 守卫之外。整个排除掉这个成员,等于为了藏起一个真的结果而丢掉另一个同样真的结果。
4646

4747
**门槛是「没有任何清单键伸得进去」。** 上游源码在预处理期发问,算;本索引自己生成的配置头,不算,那属于配方。`curl` 的 `linux/tcp.h` 就是后者——`pkgs/c/compat.curl.lua` 在 `#if defined(__linux__)` 里写了 `#define HAVE_LINUX_TCP_H 1`,把一个关于内核的正确事实读成了关于「装了哪些 userspace 头」的断言。
4848

@@ -55,13 +55,24 @@
5555
| 目标 | 首条诊断 | 真因 |
5656
| --- | --- | --- |
5757
| `x86_64-linux-gnu` | `lib/setopt.c:31: 'linux/tcp.h' file not found` | `#if defined(__linux__)` 里写死了 `#define HAVE_LINUX_TCP_H 1`。内核**确实**是 Linux,谓词没错;错的是把它读成「glibc 的 userspace 头都装好了」。诚实的判据是 `__has_include(<linux/tcp.h>)`。同一个块里还有 `HAVE_GLIBC_STRERROR_R`,在 musl 上它是假的。 |
58-
| `x86_64-windows-gnu` | `curl_setup.h:591: "too small curl_off_t"` | 配方的 `windows` 分支**有意**不定义 `HAVE_CONFIG_H`,好让 `curl_setup.h` 去取仓库里checked-in 的 `lib/config-win32.h`,并链 `-lws2_32` 走 Schannel。而在 openkal 上,那个目标呈现的是 POSIX 且是 **LP64**,`config-win32.h` 写的是 LLP64 与 Win32 API。 |
58+
| `x86_64-windows-musl` | `curl_setup.h:591: "too small curl_off_t"` | 配方的 `windows` 分支**有意**不定义 `HAVE_CONFIG_H`,好让 `curl_setup.h` 去取仓库里checked-in 的 `lib/config-win32.h`,并链 `-lws2_32` 走 Schannel。而在 openkal 上,那个目标呈现的是 POSIX 且是 **LP64**,`config-win32.h` 写的是 LLP64 与 Win32 API。 |
5959

6060
**第二条才是有意思的那条:配方按「平台」分支,而问题问的是「C 环境」。** 在 openkal 于 Windows 上呈现 POSIX 之前,这两者在本索引的每一个目标上都同答案。mcpp 有那个真正被问的谓词——`cfg(c-abi = "musl")`(mcpp docs/22「按解析出的目标侧适配」)。在那里改选生成的 POSIX 配置而不是 checked-in 的 Win32 配置,就是它的形状;它还需要本索引的 OpenSSL 跑在同一个环境上,所以比第一条大,不与它合并。
6161

6262
## 3. 何时运行
6363

64-
`.github/workflows/openkal-compat.yml` 每周运行、可手动触发,测量全部列出的成员。对 PR,openkal 家族或 `tests/openkal` 变化时测量全部成员,否则测量依赖了被修改描述符的成员。除非启用下文的比较,它不阻止合并。
64+
`.github/workflows/openkal-compat.yml` 每周运行、可手动触发,测量全部列出的成员。对 PR,`compat.py select` 只测量改动可能影响的成员:
65+
66+
| PR 改动了 | 测量的成员 |
67+
| --- | --- |
68+
| openkal 家族描述符、`pins.toml`、`compat.py`,或 `tests/openkal/` 下除 `members.toml` 以外的文件 | 全部列出的成员:依赖图或测量工具变了 |
69+
| `members.toml` | 与基准分支相比,条目新增或改动的成员;`[not-portable]` 声明计入它所指的成员,`[excluded]` 不选中任何成员 |
70+
| `tests/examples/<成员>/` | 该成员(若已列出) |
71+
| `pkgs/` 下的描述符 | 测试项目依赖该描述符的已列出成员 |
72+
73+
因此新增一个成员只测量该成员,而不是整张列表。除非启用下文的比较,它不阻止合并。
74+
75+
目标为 `x86_64-linux-gnu` 与 `x86_64-windows-musl`。Windows 目标按依赖图在那里呈现的 C 环境命名,即 musl 的,而不是 MinGW 的。2026-09-23 之前测得的结果记为 `x86_64-windows-gnu`,即该目标当时的名字。
6576

6677
它有意安装宿主的 Windows 交叉头文件。若构建触及宿主头文件,结果会因其存在而改变;结果不变即说明依赖图是封闭的。
6778

‎tests/check_mirror_urls.lua‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
-- urls remain valid and are left to the author):
55
-- * a url table must define BOTH `GLOBAL` and `CN`
66
-- * both values must be non-empty strings
7-
-- * `CN` must be a gitcode.com/mcpp-res/<repo>/releases/download/... URL
7+
-- * `CN` must be a gitcode.com/<owner>/<repo>/releases/download/... URL.
8+
-- The owner is usually the index's `mcpp-res` organization, and may be
9+
-- the library's own maintainer, who then keeps that mirror in step with
10+
-- the GLOBAL asset (same bytes, same sha256).
811
-- * `GLOBAL` must not itself point at the mcpp-res CN mirror
912
--
1013
-- Usage: lua5.4 tests/check_mirror_urls.lua <file.lua>
@@ -41,8 +44,11 @@ local function check_url(ctx, u)
4144
if type(c) ~= "string" or c == "" then
4245
err(ctx .. ": url table missing non-empty CN")
4346
end
44-
if type(c) == "string" and not c:match("^https://gitcode%.com/mcpp%-res/") then
45-
err(ctx .. ": CN url must be under https://gitcode.com/mcpp-res/ (got " .. tostring(c) .. ")")
47+
if type(c) == "string"
48+
and not c:match("^https://gitcode%.com/[^/]+/[^/]+/releases/download/[^/]+/[^/]+$") then
49+
err(ctx .. ": CN url must be a gitcode.com release asset, "
50+
.. "https://gitcode.com/<owner>/<repo>/releases/download/<tag>/<file> (got "
51+
.. tostring(c) .. ")")
4652
end
4753
if type(g) == "string" and g:match("^https://gitcode%.com/mcpp%-res/") then
4854
err(ctx .. ": GLOBAL url must not point at the CN mirror")

0 commit comments

Comments
 (0)