MSVC 模块构建的三处陈述都过期了(一句劝退用户的假 note + 一条自相矛盾的测试注释 + 一个跳过两平台的覆盖缺口) #412
Description
三件小事,同一个根源:关于 MSVC 模块构建状态的三处陈述都过期了,而代码早就走通了。它们互不依赖,但一起修最省事。
发现于 #411 收尾时追查「.ixx 在三家编译器上到底能不能用」。
1. mcpp toolchain default msvc 印一句过期的假话(用户可见)
src/toolchain/lifecycle.cppm:664:
std::println("note: `mcpp build` with native MSVC (cl.exe) is not yet "
"supported — coming in a later release.");
return 0;但它是假的。 判据两条:
-
grep -rn "CompilerId::MSVC" src/build/*.cppm的 6 处命中没有一处是拒绝/早退 —— 全是走不同分支(VC tools 探测、方言选择、命名)。构建路径里没有 MSVC 的门。 -
tests/e2e/99_msvc_native_build.sh断言的是一次完整的原生模块构建:out=$("$MCPP" build 2>&1) || { echo "FAIL: msvc build"; exit 1; } [[ "$run_out" == *"cl-ok"* ]] # 跑出结果 find target -path "*ifc.cache*" -name "*.ifc" | grep -q . # 产出 .ifc
它在
toolchains + regressions (windows x64)里以-e -o pipefail执行,该 job 绿。
这句 note 的实际效果是劝退一个能用的功能:用户切到 msvc,看到"还不支持",就不会去试。
修法:删掉这行,或改成陈述当前真实状态(例如 .ifc 管线已就位、已知限制是什么)。
2. tests/e2e/95_msvc_system_toolchain.sh 的头注释与它自己的断言矛盾
第 9 行:
# - `mcpp build` fails with the owned "not yet supported" gate message
而这个文件里没有任何一条断言在做这件事 —— 它的断言在第 35–59 行,全部止于工具链探测/选择/pin 校验。
95 说 build 会被 gate 挡住,99 说 build 会成功并产出 .ifc,两者同时绿 —— 因为 95 那句只是注释。
修法:把这行从头注释里删掉。
3. ⚠️ 217_module_extensions.sh 在 Windows 与 macOS 上整条被跳过
tests/e2e/217_module_extensions.sh 第 2 行是 # requires: gcc。而 run_all.sh 明确不在 Windows / macOS 上授予 gcc:
# NOTE: Windows runners may have g++.exe (MinGW/Strawberry) in PATH
# but it's not a proper mcpp-compatible GCC. Don't add gcc capability.
# macOS g++ is Apple Clang, not real GCC — don't add gcc capability.⇒ [build] module_extensions 只在 Linux 上被测过(那里覆盖了 GCC 与 Clang 两条腿)。
后果:「用户声明 module_extensions = [".ixx"] 然后在 MSVC 上构建」这条路没有任何测试走过。 它推理上必然通(.ixx 是 cl 的原生后缀,而 mcpp 无条件发 /interface /TP),但推理不是测量。macOS 同理(那边默认 LLVM,等同已验证的 Clang 档,同样没测)。
这与 #411 里指出 #272 的问题是同一形状——「# requires: elf gcc 让 Clang/MSVC 从未被走到」——只是程度轻一些。
修法:补一条不依赖 gcc 能力的 219,按平台选默认工具链(Windows→msvc + llvm,macOS→llvm),验证 .ixx / .ccm 走完 build→link→run。
为什么值得一起修
三条都是**「写下来的状态」与「实际行为」脱节**:两处陈旧文字 + 一处没被测试覆盖到的平台。修完之后,「mcpp 在 MSVC 上支持模块构建、并且 .ixx 可以通过 module_extensions 使用」这句话就有了代码、文字、测试三方一致的支撑。
已知事实速查(供实施时参考)
| 编译器 | 驱动原生认 .ixx? |
mcpp 发什么 | 验证状态 |
|---|---|---|---|
MSVC cl |
✅ 原生(它自己的约定) | /interface /TP |
模块构建 e2e 99 绿;.ixx + module_extensions 未测 |
| GCC 16.1.0 | ✅ | -x c++ |
e2e 217 四后缀 build→link→run ✅ |
| Clang 22.1.8 | ❌ 当链接输入,退出码 0 且不产 BMI | -x c++-module |
e2e 217 四后缀 build→link→run ✅ |
反过来 .cppm 是 GCC/Clang 认、cl 不认的那个(ninja_backend.cppm:666 原话:"our module interfaces are .cppm, unknown to cl")。两家互为盲区,所以 mcpp 每次都显式声明,不去维护"谁认哪个后缀"的表 —— 那张表会随编译器版本过期,而错了是退出码 0 的静默空转。
Activity
docs: 七个 issue(#412 #415 #416 #417 #418 #421 #422)的逐条核实与修复方案
fix(msvc,manifest,docs): #421-A #412-1 #412-2 #422 #418; bump to 2026…
test(e2e): #412-3 — module_extensions on the platform's default toolc…
feat(bench): cross-platform benchmark suite, and the defects it expos…
speak-agent commentedon Aug 31, 2026
三条都已处理,随 2026.8.15.1(commit
c459cf2)发布 —— 关闭得晚了,补记在此。1. 那句劝退用户的假 note —— 已删。
src/toolchain/lifecycle.cppm里不再有 "native MSVC (cl.exe) is not yet supported"。issue 给的两条判据都复核过:构建路径里没有 MSVC 的门,tests/e2e/99_msvc_native_build.sh断言的是一次完整的原生模块构建并产出.ifc。2. e2e 95 的头注释与自身断言矛盾 —— 已删掉那一行。
tests/e2e/95_msvc_system_toolchain.sh现在的头注释只描述它真正断言的东西:msvc@system 的探测、选择、toolchain list的 System 段、版本化 msvc spec 不是这个来源、以及 mcpp 从不接管机器上的 VS。3. 覆盖缺口 —— 新增
tests/e2e/236_module_extensions_default_toolchain.sh。第三条没有按「把 217 的
# requires: gcc去掉」来修,因为run_all.sh拒绝在 Windows / macOS 上授予gcc的两条理由都成立(那两台上的g++分别是 MinGW/Strawberry 与 Apple Clang)。236 是一个不申请任何 capability 的独立文件,用平台默认工具链跑 —— Windows 上是 MSVC、macOS 上是 LLVM、Linux 上是 GCC —— 所以它到得了 217 到不了的那两条腿,其中就包括「声明.ixx并用 MSVC 构建它」这个真实的移植路径。236 的头注释把这个理由写在文件里了,并点名它是 #272 的同一形状:那次
# requires: elf gcc意味着 Clang 与 MSVC 两条腿从未被跑到。