现象
三步递进,每一步都被引擎指向下一步,最后撞在同一处。
1. 裸目标被拒,且不在可构建列表里
$ mcpp build --target x86_64-windows-gnu
Resolving toolchain
error: target 'x86_64-windows-gnu' cannot be built on this host.
No toolchain payload here produces it, and nothing in the dependency graph
supplies its system side.
this host can build with the payload alone: aarch64-macos, riscv64-none-elf,
riscv32-none-elf, aarch64-none-elf, x86_64-none-elf, thumbv6m-none-eabi, ...,
x86_64-openkal, aarch64-openkal
To build it anyway, depend on a package that implements the target's system
(its kernel interface and C library), or supply your own cross toolchain with
an explicit [target.x86_64-windows-gnu] toolchain = "…" section.
附带一点:mcpp toolchain list 在 macOS 上根本不列出任何 windows 目标(x86_64-openkal 在,x86_64-windows-gnu 不在)。对比 #782 里 ubuntu-24.04-arm 的实测——那里行是列出来的,只是拒绝时不给理由。macOS 上是静默隐身。
2. 逃生口 A(自带工具链)是一个不存在的拼写
按上面最后那句提示照做:
[target.x86_64-windows-gnu]
toolchain = "/opt/homebrew/bin/x86_64-w64-mingw32-g++"
error: [target.x86_64-windows-gnu].toolchain = '/opt/homebrew/bin/x86_64-w64-mingw32-g++':
unknown toolchain '/opt/homebrew/bin/x86_64-w64-mingw32-g++'
(expected gcc | llvm | msvc | emsdk | android-ndk, or a supported alias like mingw / musl-gcc)
toolchain 只解析 family name(src/toolchain/registry.cppm:605 走 compat::normalize_spec),
不吃路径。所以这条诊断在给用户指一个解析器不接受的写法——照做必然撞墙。
homebrew 的 mingw-w64 恰好能提供 macOS 宿主的原生交叉 GCC,但没有入口用它。
3. 逃生口 B(依赖图供 system side)走到一半
[features]
openkal-cross = {}
[feature-deps.openkal-cross]
openkal-llvm-runtime = "0.19.2"
$ mcpp build --target x86_64-windows --features openkal-cross
Resolved [email protected] → x86_64-windows-gnu → …/xpkgs/xim-x-llvm/23.1.3/bin/clang++
Target x86_64-windows → x86_64-w64-windows-gnu
compiler-runtime compiler-rt ([email protected], graph)
kernel-abi openkal ([email protected], graph)
c-abi musl ([email protected], graph)
c++-abi libc++ ([email protected], graph)
Compiling compat.glfw v3.4.0.1
error: build failed in compat.glfw v3.4.0.1
failed: obj/compat_glfw/src/win32_time.o
…/compat-x-glfw/3.4.0.1/src/win32_platform.h:68:10: fatal error: 'windows.h' file not found
68 | #include <windows.h>
| ^~~~~~~~~~~
编译器这一步已经通了:clang 出 PE、libc++/musl/compiler-rt 全部就位,我自己的
C++20 源码(import std,含 imgui backends)全部编译通过。卡住的只有 glfw 的 Win32 后端:
win32_platform.h 一声 #include <windows.h>,12 个 win32_*.c 全部死在同一行。
归属:缺口是 system side,不是编译器
引擎的 note 自己给了方向:
note: musl ([email protected]) comes from the dependency graph, and the host's own
C library headers are not searched …
A package that needs the header above has to adapt, either:
(a) to this C library, in the package's own descriptor
(b) by bringing the platform headers it needs into the dependency graph as
its OWN dependency, private to itself (docs/06 'A platform SDK
dependency stays private')
(b) 在 macOS 宿主上是空的。索引实测(~/.xlings/data/xim-pkgindex/pkgs/):
| 包 |
声明的宿主 |
提供什么 |
mingw-gcc |
xpm.windows |
winlibs UCRT 完整工具链,自带 CRT 头 + 导入库 |
mingw-cross-gcc |
xpm.linux.x86_64 |
Linux 宿主原生交叉 GCC,自带 binutils + CRT + libstdc++ |
windows-sdk |
xpm.windows |
MSVC ABI 的 ucrt/um/shared 头 + .lib,靠 msiexec /a 解包 |
[email protected] |
依赖图 |
只有 kal_* kernel-abi,包内无 windows.h(已 find 确认) |
于是三宿主矩阵缺一个角:
Windows 宿主 ✓ mingw-gcc(自带 Win32 头 + 导入库)
Linux 宿主 ✓ mingw-cross-gcc(同上)
macOS 宿主 ✗ ← 本 issue
Windows 宿主上同一个工程 mcpp build 8.34s 全绿、10 个 exe 出齐(我在
DESKTOP-0PJI1SO 上实测)。同一份源码、同一个 mcpp.toml,只换宿主,结果从"能出 exe"
变成"连一个字节都出不来"——缺的既不是源码兼容性也不是编译器,就是这个 system side 包。
为什么 openkal 目标不能替代(先排除这一条)
x86_64-openkal 在 macOS 上确实能 build、能 pack:
$ mcpp pack --target x86_64-openkal
Packed target/dist/hello-0.1.0-openkal.tar.gz
$ file lib/x86_64/hello.oke
ELF 64-bit LSB shared object, x86-64, static-pie linked
但它产出的是 .oke 映像 + bin/hello.cmd(内容 "okrun" "%image%" %*),运行依赖目标机装
okrun,不是可直接分发的 PE。而 openkal 规范的接口面是 kal_*(stream/fs/time/env/memory/
random/abort/terminal/net/task),没有窗口/图形/GPU——glfw 的 Win32 后端要 <windows.h>、
user32/gdi32/dwmapi 导入库与 WGL,这些仍然只能来自 MinGW 的 system side。
所以 openkal 解决的是"任何宿主编译任何架构",代价是放弃目标平台原生 ABI;
本 issue 要的是保留原生 ABI 的那条路。
期望
任一即可,按投入从小到大:
-
纯数据 payload(推荐,最小):发布一个 mingw-w64-headers 之类的宿主无关包,
只含 Win32 头(windows.h/windef.h/winuser.h/…)+ lib*.a 导入库,不含编译器
(约几十 MB,纯数据,无 ABI 依赖)。这样 compat:glfw 这类平台绑定包就能按 note (b)
把它声明成自己的私有依赖,任何宿主的 clang 都能出 PE。
这条路不需要重新构建交叉 GCC,也不动 host_can_serve 的判定。
-
给 mingw-cross-gcc 加 macosx payload(arm64 + x86_64):等价于 homebrew 的
mingw-w64,与现有 linux-x86_64 包同构,自带 CRT 头 + 导入库 + libstdc++。
同时需要把 registry.cppm:1383 的 host_can_serve 从
is_linux && host_arch == "x86_64" 放宽到"索引声明了该宿主"——
那里的注释已经预告过这次改动("a payload for it does not exist on any host" 之类
的常量判定应当由索引回答)。
-
顺手修一下诊断:[target.<triple>] toolchain = "…" 提示与解析器不一致
(第 2 节)。要么让 toolchain 接受路径并探测其 target/sysroot,要么把这句提示改成
toolchain = "[email protected]" 这类真实存在的写法。现状是引擎自己把用户送进死胡同。
环境信息
- mcpp 2026.11.7.2(
34406d63,mcpp self version 与 tag 一致)
- 宿主:macOS 15 (Apple Silicon, arm64),默认工具链
llvm 23.1.3
- 工程:glfw 3.4.0.1 + Dear ImGui 1.92.8 + glad(全部来自
compat:*)× import std
- Windows 宿主对照组:DESKTOP-0PJI1SO(msvc 19.51 / VS 2026),同一份
mcpp.toml 8.34s 全绿