sync: 工具链 pin 跟进 — mcpp → 2026.8.1.1,d2x → 2026.08.02.1 - #87
Merged
Conversation
mcpp 侧不是升级偏好,是必须:mcpplibs 依赖索引已把 index floor 抬到 0.0.109, 钉在 0.0.104 的工程一律 E0006「index requires mcpp >= 0.0.109」而拒绝解析依赖。 d2x 仓库的 CI 因此一度全平台红,并为本课程加了一步「安装前把 pin 对齐」的 workaround —— 本次同步之后那步就可以撤掉了。 d2x 侧跟到刚发布的 2026.08.02.1:Win10 / Win11 CI(完整测试段 + 以本课程做 checker 真实冒烟)、Windows 上练习页路径显示修复、Windows 活性超时补齐。 CI 头部注释一并更新:原文只写了「依赖 mcpp >= 0.0.104」,而真实下限已被上游 抬到 0.0.109,不写清楚下一个人会以为 0.0.104 还能用。
Windows 上每道练习都判不出结果,现象是 Provider 报「mcpp test 没有返回
'<test>' 的记录」,看起来像 mcpp 不支持 --message-format json —— 实际是本仓库
Provider 自己的问题。
capture_stdout 无条件给命令尾巴上接 ` 2>/dev/null`。Windows 上 _popen 走的是
cmd.exe,那里没有 /dev/null:cmd 把它当成「重定向到 \dev\null 这个路径」,而
\dev 不存在,于是直接报
The system cannot find the path specified.
并且整条命令根本不执行。mcpp test 一条 JSON 都没吐,解析侧 saw_any 为假,判定
链退化成「没有该测试的记录」,那句「mcpp 可能不支持 --message-format json」的
提示把锅指错了方向。
证据(d2x 的 Win10 / Win11 checker 冒烟实测):
外层 `mcpp run -q -p d2x/buildtools -- check hello-mcpp` 本身跑得通 —— 说明
mcpp 在 PATH 上(不在的话 cmd 会报 'mcpp' is not recognized,是另一句话);
只有内层带 2>/dev/null 的 mcpp test 挂掉。两者唯一的差别就是这个重定向。
空设备在 cmd 下叫 NUL,按平台分开写即可。POSIX 分支拼出的字符串与改前逐字节
相同,linux 行为不变;本地实测 check hello-mcpp 仍是 stage → output(真实编译
错误)→ verdict fail。
Member
Author
已在真实 Win10 / Win11 runner 上验证通过把 d2x 的 checker 冒烟临时指向本分支跑了一轮(d2learn/d2x#35,draft),并把 Windows 的判据收紧到与 linux 同档(必须透出真实编译错误,且断言 修复前(Windows): 修复后(windows-2022 实测输出):
顺带确认 d2x 侧那条 Windows 路径显示修复也生效: 合并顺序本 PR 合入后,d2x#35 会把临时的 |
Sunrisepeak
added a commit
to d2learn/d2x
that referenced
this pull request
Aug 1, 2026
* fix(windows): 活性超时终止后不再可能空转;冒烟判据收紧到与 linux 一致 两处与「Windows 上 checker 卡住」直接相关。 1) run_lines_idle 终止之后可能永远空转 Windows 分支里 killed 置位后,唯一的出口是 WaitForSingleObject 变有信号。 若终止没生效(Job 纳管被拒、TerminateJobObject 被拒、进程卡在不可中断态), 循环就以 50ms 一轮永远转下去 —— 这个循环存在的意义正是防挂死,它自己挂死 是最糟的结局。改成两级兜底:5s 后补一次 TerminateProcess(Job 路径失败时 还有救),15s 后放弃等待、如实返回 idle_killed,退出码沿用 POSIX 分支被 KILL 时的 128+9。 2) Windows 冒烟判据收紧 此前 Windows 这一档不要求透出编译错误,因为 d2mcpp 的 Provider 在 capture_stdout 里给命令接了 —— cmd.exe 没有 /dev/null,报 "The system cannot find the path specified." 且 mcpp test 根本不执行。 该问题已在 mcpp-community/d2mcpp#87 修掉,这里同步收紧到与 linux 同档, 并额外断言那句 cmd 报错不再出现,防止回归静悄悄溜回来。 TEMP:两处 d2mcpp checkout 暂时指向 #87 的分支以便在真 Windows 上验证;该 PR 合入后改回默认分支。 * ci: d2mcpp ref 改回默认分支,并删掉已失效的 pin 对齐 workaround d2mcpp#87 已合入 main:Provider 的 2>/dev/null 修好了,课程侧的 mcpp pin 也同步 到 2026.8.1.1。于是两件事可以收尾: - 两处 d2mcpp checkout 的临时 ref 去掉,回到默认分支 —— 此后 Windows 的收紧判据 长期守的是 d2mcpp main,回归会立刻现形。 - 两处「Align course mcpp pin」workaround 删除:它存在的唯一理由是课程钉在 0.0.104 会撞 mcpplibs 索引下限,现在课程自己已经钉对了。
This was referenced Aug 2, 2026
Sunrisepeak
added a commit
that referenced
this pull request
Aug 2, 2026
* docs+ci: 本地上手三步走 + 平台矩阵拆分(linux/macos/win10/win11/win 无 MSVC STL)
README(三语 + book 两语)重写「本地练习环境」段,改成明确的三步:
1. 装工具 —— `xlings install d2x mcpp -y`,两个工具名都链到各自仓库
2. 取课程并验证环境 —— 默认 `d2x install d2mcpp` → `cd d2mcpp` → `mcpp test`;
clone 源码那条路收进 <details>,作为可选项而不是与默认路径并列的「二选一」
3. 开始练习 —— `d2x checker` / `d2x status`
第 2 步把 `mcpp test` 摆到台面上是有意的:练习就是测试,新环境跑一遍
「全部不通过」既是练习的起点,也已经证明工具链是通的。
CI 从单个 ubuntu job 拆成五档平台矩阵,每档都跑完整两层验证:
linux / macos / windows-10 线(windows-2022)/ windows-11 线(windows-2025)
/ windows 且无 MSVC STL
最后一档把 runner 上的 Visual Studio 藏掉(改名 vswhere.exe 与 VC 目录 +
清空 VS* 环境变量,并就地检查后置条件),模拟学习者的干净 Windows —— 这
才是多数人的机器。mcpp 应当自动回落到自带的 winlibs MinGW,产物 target
目录名(x86_64-windows-gnu)就是断言依据。
两层验证:
- `mcpp test`(已有 e2e.sh)—— pristine 全不过 + 覆盖答案后全过
- `d2x checker`(新增 checker-e2e.sh)—— 答案就位后 checker 必须自己走完
52 道题并退 0
加第二层是因为 checker 在 mcpp test 之上还叠了 Provider 的 NDJSON 协议、
进度持久化、文件监听三层;这三层断掉时 mcpp test 照样全绿,Windows 上就
出过这种静默回归(#87)。checker-e2e.sh 的看门狗自己用 shell 轮询实现,
不依赖 timeout(1)(macOS 默认没有)。
顺带:
- .xlings.json pin 上抬 —— mcpp 2026.8.1.1 → 2026.8.2.1(裸 Windows 自动
回落 MinGW 是这个版本才有的能力,无 MSVC STL 那一档依赖它),
d2x 2026.08.02.1 → 2026.08.02.2
- 修复文件名核对 job:它还在按迁移前的布局找 `intro/tests cpp*/tests`,
练习早已搬进 src/,于是一个文件都没扫到、永远绿。现在真的核对 52 对。
- 工作流触发路径补上 .xlings.json
本地已验:e2e.sh all(zh/en 各 52/52)、checker-e2e.sh zh 与 en 均全过。
* docs(book): chapter_1 补上工具安装与环境验证,与 README 三步对齐
chapter_1 是三份 README 的「更多细节」落点,但它的 §0 只装 xlings,
接着就直接 `d2x install d2mcpp` —— 一台干净的机器照着做会在第二条命令
上失败,因为 d2x 这个二进制根本还没装。
补两处,与 README 新的三步保持同一套说法:
- §0 结尾加 `xlings install d2x mcpp -y`,两个工具名链到各自仓库
- §1 加「验证环境」小节:`cd d2mcpp` + `mcpp test`,并说明「刚拿到课程
时全部未通过」既是起点也是工具链已通的证据
* docs: 改掉 step 2 里「每道练习都能编译并运行」这句错话
原话把 `mcpp test` 说成「验证每道练习都能编译并运行」,正好说反了:练习发
下来就是没做完的,`std:endl`、`D2X_YOUR_ANSWER` 这类东西**必然编不过**,
pristine 状态下 0 passed 才是对的(e2e.sh 的断言 1 就是在守这条)。
顺带澄清一个容易误会的点:`solutions/` 不是工作区成员(mcpp.toml 的
members 里没有它),`mcpp test` 从头到尾不碰它。要它变绿得先覆盖到练习
文件上——那是 CI 的动作,不是学习者跑一条命令就会发生的事。
改成说清楚它到底验了什么:工具链解析成功、d2x 库编译通过、运行器逐题都
跑到了;练习本身红着是设计如此。README 三语 + book 两语 + chapter_1 两语
共 7 处同步。
* feat(solutions): 参考答案自己成为一个 mcpp 工程,`mcpp test -p solutions` 直接跑
在此之前 solutions/ 只是一堆躺在磁盘上的 .cpp:不是工作区成员,mcpp 从头到
尾不认识它。想验证答案对不对,唯一的办法是把 52 个文件覆盖到 src/*/tests/
上、跑一遍、再 git 还原 —— 一套带副作用、要求工作树干净、只有 CI 脚本会用
的流程。学习者或贡献者想确认「答案是好的」,没有一条命令可以跑。
现在 solutions/ 是一个正经工程:
solutions/mcpp.toml name=solutions, c++23, 依赖 d2x
solutions/tests/<std>/... 52 份答案,就是它的测试
于是:
mcpp test -p solutions # 52 passed; 0 failed
mcpp test -p solutions cpp11 # 按子串筛
零副作用、不碰练习目录、任何人随手可跑。布局与练习一一对应,测试名
(intro/hello-mcpp、cpp11/00-auto-and-decltype/0) 直接对回练习文件。
配置刻意与练习工程一致(c++23 + d2x),否则「答案能过」推不出「答案放进
练习里也能过」。
覆盖-还原那套 e2e 保留 —— 它验的是另一件事:答案放到练习的位置上也成立,
且练习在未完成时确实不通过。两条互补:新的这条挂了说明答案本身是错的,
旧的那条挂了说明答案与练习对不上。
- e2e.sh 新增 solutions_selftest(),并核对测试条数 == 答案文件数:测试发现
是按 tests/**/*.cpp 自动扫的,布局一改就可能一个都没扫到,而「0 个测试」
在 mcpp 眼里同样是 "test result ok"
- CI 每档平台新增独立一段 `mcpp test -p solutions`,排在覆盖-还原之前,
失败定位最短
- e2e.sh / checker-e2e.sh / 文件名核对 job 的路径映射跟随改为 solutions/tests/
* docs: step 2 的环境验证改用 `mcpp test -p solutions`
上一版让 step 2 跑裸 `mcpp test`,然后解释「全红是对的」。这在逻辑上站不住:
工具链坏掉时也是全红,学习者看着同样的输出,分辨不出是自己还没做题还是环境
没装好——一个只会红的命令没法用来验证环境。
solutions/ 成为工程之后就有了确定的绿:
mcpp test -p solutions # 验证环境: 52 份参考答案, 应当全绿
mcpp test # 你的进度表: 练习还没做, 此刻全红
两条命令各自含义明确:第一条绿 = 工具链没问题;第二条红 = 你的起点。
README 三语 + book 两语 + chapter_1 两语同步。chapter_1 里另外写清了答案与
练习靠 tests/ 相对路径配对,以及 `mcpp test -p solutions cpp11` 的筛选用法。
撰稿技能(.agents/skills/d2mcpp-authoring)的路径与「答案怎么验」也跟随更新:
新增答案后可以直接 `mcpp test -p solutions <slug>` 自查,不必再走覆盖流程。
* docs: step 2 只留环境验证,进度表挪到 step 3 的可选 note
step 2 摆两条命令、再解释「第一条绿第二条红」,等于在验证环境这一步塞了
一个当下用不上的概念。step 2 现在只做一件事:
mcpp test -p solutions # 验证环境: 52 份参考答案, 应当全绿
裸 `mcpp test`(你自己的进度表)本来就属于「不经过 d2x 怎么练」这一类,
归到 step 3 已有的那条可选 note 里,和 `mcpp test -p src/cpp11` 放一起:
> 不想经过 d2x? 练习就是测试 —— `mcpp test` 打印你的完整进度表(动手前
> 全红), `mcpp test -p src/cpp11` 只跑某一章。
同步的地方:
- README 三语 + book 两语:step 2 收敛为一条命令;<details> 里 clone 那条
路的环境验证也跟着改成 `mcpp test -p solutions`(原来还是裸 mcpp test)
- chapter_1 两语:「验证环境」节同样只留参考答案那条;裸 `mcpp test` 落到
已有的「原生模式(可选)」节,作为该节三条命令里的第一条
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
mcpp:不是升级偏好,是装不出来了
mcpplibs依赖索引已把 index floor 抬到 0.0.109,钉在0.0.104的工程一律:依赖(
compat.ftxui等)直接拒绝解析。d2x 仓库的 CI 因此一度全平台红,并为本课程临时加了一步「安装课程工具链前先把 pin 对齐」的 workaround
(d2learn/d2x#33)。本次同步之后,那步
就可以从 d2x 侧撤掉了。
d2x:跟到刚发布的 2026.08.02.1
2026.08.02.1已发布,GitHub / GitCode 双源资源就位(均以 GET 实测校验 sha256与源一致),
xlings install d2x@2026.08.02.1本地实测可装、d2x --version正确。该版内容里有两件与本课程直接相关:
拉起 Provider、枚举练习、渲染第一题,而不只是「能编过」。
\src\intro\tests\hello-mcpp.cpp(多一个前导分隔符),现在与 linux 一致为
src/intro/tests/hello-mcpp.cpp。一并更新 CI 头部注释
原文只写「依赖 mcpp >= 0.0.104」,而真实下限已被上游抬到 0.0.109 —— 不写清楚,
下一个人会以为 0.0.104 还能用。
已知的上游遗留(不在本 PR 范围)
Windows 上
mcpp test --message-format json会先以「找不到路径」失败,导致本课程的 Provider 发不出 verdict:
d2x 侧行为是对的(协议规定「Provider 没给 verdict 即 fail」),这条属 mcpp /
本仓库 Provider 在 Windows 上的问题,待另行排查。