refactor(pm): move publish/xpkg_emit.cppm into pm/publisher.cppm (PR-R6) - #9
Merged
Merged
Conversation
Step six of the package-management subsystem refactor (see `.agents/docs/2026-05-08-pm-subsystem-architecture.md`). Strictly zero behavior change. * New module `mcpp.pm.publisher` (`src/pm/publisher.cppm`) carries the full xpkg-emission implementation — `emit_xpkg`, `placeholder_release`, `release_tarball_url`, `sha256_of_file`, `make_release_tarball`, `make_release_info` — under the `mcpp::pm` namespace. * Old `mcpp.publish.xpkg_emit` (`src/publish/xpkg_emit.cppm`) is now a thin shim. Aliases use **using-declarations** (not inline forwarders) because `ReleaseInfo` lives in `mcpp::pm`; ADL on a `ReleaseInfo` argument would otherwise see two distinct candidates (the inline forwarder + the new mcpp::pm function) and fail with "ambiguous overload" inside `tests/unit/test_xpkg_emit`. The using-declaration introduces the same symbol into both namespaces — single overload, ADL stays clean. Verification: * `mcpp build` compiles unchanged. * `mcpp test` — 9/9 unit binaries pass (including the previously- ambiguous `test_xpkg_emit`). * e2e: 02 / 06 (emit_xpkg) / 09 / 12 / 27 all pass. `src/publish/` will be deleted entirely once `cli.cppm` migrates to the `mcpp::pm::` qualified names directly.
Sunrisepeak
added a commit
that referenced
this pull request
Sep 7, 2026
一句话:**引擎与规则层早就与平台无关,而生态只在 Linux 上完整**;把规则包在另外两个
平台上真跑一遍,暴露了三处缺陷 —— 一处已修、一处**我的修复被实测推翻**、一处是使用者
会撞上的规则。
设计文档:`.agents/docs/2026-09-07-heterogeneous-cross-platform-ecosystem.md`(含 §10
实施回填)。
## 一、`examples/10-graphics/offscreen`:一条真实的图形管线,判据是像素
此前所有异构示例都是**计算**。这一个是**图形**:顶点与片段两个着色器阶段、一条 render
pass、`vkCmdDraw` 画一个三角形、`vkCmdCopyImageToBuffer` 取回像素。
**离屏,而不是开窗**,因为那是可断言的形态:无窗口、无交换链、无表面扩展,在没有显示器
的 runner 上跑得起来,而结果是一段可以逐字节检查的缓冲区。程序自己断言四角等于清除色、
中心不等于清除色、三个通道都非零、alpha 为 255。
同一道接缝背后是一个自己写的软件光栅器。**实测两条腿的中心像素逐字节相同**
(`(124, 70, 62, 255)`),所以 CI 的反向腿断言的是「两条腿报出同一个像素、不同的设备名」
—— 图像是契约,设备名是唯一区分它们的东西。
CI 还在 macOS 与 Windows 上各构建一次(不跑,那两台没有 Vulkan 设备):断言的是**这个
平台用的那个着色器编译器**产出两个 SPIR-V 头、Vulkan 那一半编译并链接得上 loader 包。
### 一条使用者会撞上的规则:**依赖不能被 layer 条件化**
`cfg(accelerator = ...)` 下的 `[build]` 源生效而**依赖被忽略**,于是包被丢掉、包含它的
源被留下,构建死在 `vulkan/vulkan.h: No such file or directory`。示例 README 把这一条
写成了正文。
## 二、版本约束里的 `>` 被 cmd.exe 读成重定向(Windows)—— 已修
Provisioning [xlings.workspace] entries declared by dependencies (xim:shaderc@>=2026.3)
The filename, directory name, or volume label syntax is incorrect.
`shell::quote` 回答的是子进程的 argv 解析,cmd 不认那个转义,于是走到 `>` 时引号数是
偶数。`>=` 正是每个规则包声明下界用的形态,而**在此之前没有任何一条能在 Windows 上生效
的声明带过 `>`**。
修法是标准双重转义。判据是两个解析器的模拟器,断言**子进程收到的参数等于本来要传的那个
JSON**,外加一条反向腿断言旧写法确实让 cmd 看见了一个活的元字符。端到端判据在
mcpp-plugins:它今天用精确版本绕开,这个修复发布后改回 `>=`,那条 Windows job 就是端到
端判据。
## 三、macOS 14 上构建程序用不了 `std::println` —— 记录,未修,而且是因为**修法更糟**
`std::print` 不是 header-only 的:它的支持符号在 libc++ **dylib** 里,而 macOS 14 那一版
没有。直觉的修法是让 `host_link_tokens` 的「信任 cfg」出口也发 `-L<载荷>/lib`。
**试过了,CI 推翻了它。** 那会让 `-lc++` 解析到工具链自己的 dylib,也就是
`dist::mechanism_for` 在 Mach-O 上明确拒绝的 ToolchainCoupled —— LLVM 的 macOS
libc++abi 与 libunwind dylib **向上链接** `/usr/lib/libc++`,系统 libc++ 与工具链的那份
同时载入,跨两份释放的对象在 libmalloc 里 abort(#202)。CI 报的正是这条路的第一步:
链接停在 `__cxa_end_catch` 与其余那些系统 libc++ 会再导出、载荷那份不会的 ABI 符号上。
所以改回去,把这条不对称与它的理由写进代码,判据从「断言修复」改成**陈述这条决定**
(`OnlyTheSpelledOutExitNamesTheToolchainRuntimeDirs`;为此给策略枚举补了
`CfgBypass::Never`,让那条在 Linux 上不可达的分支可测)。
**限制照实写:macOS 14 上构建程序不能用 `std::print` / `std::println`。**
`std::format` 是 header-only 的,没有这个问题 —— 真正修好的那一半在 mcpp:plugins,
六个规则模块全部改用它。
## 四、文档
`docs/20` 新增「Which platforms each lane reaches」(中英双份):三件事同时为真才叫一条
lane 在某个平台上成立,而第三件(规则自己那段按宿主分岔的代码编译得过)是最容易被默认
成立的那一件。同节写明四处按宿主的差异、以及运行时适配层是 Linux 的构造 —— 它们不该被
「补到三平台」。「尚未实现」补两条按平台分的缺口,都写明缺的具体是什么。
## 生态侧(已合入)
* xim-pkgindex #778:`shaderc` 补 macOS arm64 与 Windows x86_64
* xim-pkgindex #779:CUDA 四个组件 + `dpcpp` 补 windows 段;共享 install/config 形状里
三处按宿主分的支;一条量了很久却对十五个配方从没量到过的判据(它的入口是
`content.find("xpm")` —— 文件里第一次出现这三个字母,而注释里就有)
* mcpp-plugins #9 → 0.2.5:着色器阶段冲突的拒绝、三平台各自的编译器、CUDA/SYCL 的
Windows 形态、以及一个「每条规则都为本宿主编译过」的夹具 —— 它第一批运行就抓到三处
* mcpp-index #365:`mcpp:plugins` 0.2.5
## 沙箱验证(已跑,对着已发布物)
`xlings subos use ... --sandbox`,CN 镜像,空 `$HOME`、新 `/tmp`、PATH 上没有 mcpp:
ok: Provisioning [xlings.workspace] entries declared by dependencies (xim:glslang@>=15.1.0)
ok: both stages: 354 + 124 words
ok: glslang: 15.1.0 (恰好一个版本)
本次发布后会用新的 tarball 再跑一次。
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.
Summary
Step six of the pm subsystem refactor.
Strictly zero behavior change.
mcpp.pm.publisher(src/pm/publisher.cppm) carries the fullxpkg-emission implementation under the
mcpp::pmnamespace.mcpp.publish.xpkg_emitis now a thin shim. Aliases useusing-declarations, not inline forwarders, because
ReleaseInfolives in
mcpp::pm; ADL on aReleaseInfoargument would otherwisesee two distinct candidates and fail with "ambiguous overload" in
test_xpkg_emit.Test plan
mcpp build(worktree)mcpp test— 9/9 unit binaries pass (includingtest_xpkg_emit)