|
| 1 | +# mcpp-plugins 0.15.0:职责分层、以 build.mcpp 为中心的配置与多平台运行时闭包 |
| 2 | + |
| 3 | +> 2026-09-26 · 第 3 版(吸收第 1、2 版评审)· 承接 `2026-09-26-deps-vcpkg-rules-qt-{design,plan}.md` |
| 4 | +
|
| 5 | +## 0. 总纲 |
| 6 | + |
| 7 | +核心体系由两部分组成:mcpp 通用引擎及其构建插件框架;官方、第三方或项目内的构建插件。`build.mcpp` 是这一机制的 |
| 8 | +核心使用点:项目在其中导入插件模块、配置插件并调用它。 |
| 9 | + |
| 10 | +评审提出的问题: |
| 11 | + |
| 12 | +1. Linux 上 vcpkg 端口与程序的 C++ 标准库不一致。 |
| 13 | +2. Linux 上 QtGui 不可用。 |
| 14 | +3. 插件与依赖库绑定:Qt 版本固定,运行时库写在插件的 feature 中。 |
| 15 | +4. feature 应是通用机制;依赖的选择由插件与 build.mcpp 组合配置实现。 |
| 16 | +5. 内部实现(`mcpp-deps`)不得成为消费方契约。 |
| 17 | +6. 缺少插件开发规范;README 过长。 |
| 18 | + |
| 19 | +约束: |
| 20 | +- GalTranslPP 上游仅支持 Windows。Linux 与 macOS 的判据由插件仓库的 fixture 承担,GalTranslPP PR2 作为 Windows 回归。 |
| 21 | +- mcpp 最新版本为 2026.9.26.2。 |
| 22 | +- 0.14.1 与 0.15.0 合并为一个版本 0.15.0。每个仓库一个 PR,仅在无法同时验证时拆分(§8)。 |
| 23 | + |
| 24 | +## 1. 职责分层与决定 |
| 25 | + |
| 26 | +| 层 | 负责 | 不负责 | |
| 27 | +|---|---|---| |
| 28 | +| mcpp | 构建图、动作与戳、运行时闭包检查、部署、打包、工具链信息 | 任何具体库、SDK 或工具 | |
| 29 | +| 插件 | 机制:输入变为声明了输入输出的动作;前缀或 SDK 映射进构建 | 版本;运行时闭包;绕过引擎缺口 | |
| 30 | +| xlings 包 | 载荷及其在每个平台上的运行时闭包 | 构建逻辑 | |
| 31 | +| 项目 | 策略:库、SDK、版本、路径、选项 | — | |
| 32 | + |
| 33 | +- **D1 feature 只表达机制。** feature 只能声明机制自身执行的工具(`xim:vcpkg`、`xim:cmake`),不得声明链接进程序的库或 |
| 34 | + SDK。`rules-qt-xim`、`rules-qt-xim-base`、`rules-qt-xim-addons` 在 0.15.0 **直接删除**(评审决定,不保留别名)。 |
| 35 | +- **D2 运行时闭包归提供它的包,逐平台成立**(§4)。 |
| 36 | +- **D3 内部实现不进入契约。** 契约面只有 feature 名、`options` 字段、返回类型和文档所列的环境变量。 |
| 37 | + |
| 38 | +## 2. 配置:以 build.mcpp 为中心 |
| 39 | + |
| 40 | +每项配置取第一个给出值的层级: |
| 41 | + |
| 42 | +| 级 | 位置 | 说明 | |
| 43 | +|---|---|---| |
| 44 | +| 1 | `build.mcpp` 中的 `options` | 项目配置的主要位置,值可以计算;插件的返回值(前缀、SDK 根、部署的文件)是编程扩展点 | |
| 45 | +| 2 | 约定的环境变量 | 只采用生态中已有的名字(`QT_ROOT_DIR`),变化时重新规划 | |
| 46 | +| 3 | 项目在 `[xlings]` 中声明的载荷 | 版本由项目声明 | |
| 47 | + |
| 48 | +生效层级以 `mcpp::fact` 记录。第 2 版中的 `[package.metadata.<成员>]` 一级按评审意见删除:vcpkg 的库列表属于 |
| 49 | +build.mcpp,而不是 mcpp.toml。 |
| 50 | + |
| 51 | +```toml |
| 52 | +[build-dependencies.mcpp] |
| 53 | +plugins = { version = "0.15.0", features = ["rules-qt", "deps-vcpkg"], host-module = true } |
| 54 | + |
| 55 | +[target.'cfg(any(windows, linux, macos))'.xlings.workspace] |
| 56 | +"xim:qt-base" = "6.11.1" |
| 57 | +``` |
| 58 | + |
| 59 | +```cpp |
| 60 | +// build.mcpp |
| 61 | +import mcpp.rules.qt; |
| 62 | +import mcpp.deps.vcpkg; |
| 63 | +int main() { |
| 64 | + mcpp::deps::vcpkg::options v; |
| 65 | + v.libraries = { "fmt", "spdlog" }; |
| 66 | + mcpp::rules::qt::options q; |
| 67 | + q.modules = { "Core", "Widgets" }; |
| 68 | + return mcpp::deps::vcpkg::use(v) && mcpp::rules::qt::compile(q) ? 0 : 1; |
| 69 | +} |
| 70 | +``` |
| 71 | + |
| 72 | +rules-qt 的 SDK 查找顺序为 `options::root` → `QT_ROOT_DIR`(不采用 `QTDIR`)→ 项目声明的 `xim:qt` 或 `xim:qt-base`(附带 |
| 73 | +`xim:qt-addons`)。找不到时的警告给出可直接复制的两行声明。 |
| 74 | + |
| 75 | +## 3. C++ 标准库对齐 |
| 76 | + |
| 77 | +- **deps-vcpkg**:在 Linux 的 libc++ 工具链下,默认 triplet 为生成的 `<arch>-linux-libcxx`,端口以 mcpp 的 clang 编译。 |
| 78 | +- **每个 triplet 独立安装**:前缀为 `<install root>/<triplet>/<triplet>`。 |
| 79 | +- **deps-cmake**:同样条件下传入 mcpp 的 clang。 |
| 80 | +- **rules-qt**:在 libc++ 工具链下使用 Qt 官方 Linux 构建时给出警告。 |
| 81 | + |
| 82 | +以上已完成:PR #32 的这部分三平台 CI 通过,本机 `vcpkg-libcxx` 判据通过。 |
| 83 | + |
| 84 | +## 4. 多平台运行时闭包 |
| 85 | + |
| 86 | +判据:只装有操作系统的机器上,`mcpp pack` 的产物能够启动。 |
| 87 | + |
| 88 | +| 平台 | Qt 加载的外部库 | 0.15.0 | |
| 89 | +|---|---|---| |
| 90 | +| Linux | glib、zstd、zlib、libdbus、fontconfig、freetype、X11、xkbcommon、EGL/GL、xcb 系列 | `xim:qt` 与 `xim:qt-base` 声明这些包和 `xim:glibc`。libxpkg 的加载器谓词在安装后改写载荷中的每个 ELF:可执行文件使用 xlings 加载器,RUNPATH 为这些包与载荷自身 `lib/` 的闭包。工具与程序共用一个加载器和 libc | |
| 91 | +| Windows | 系统 DLL;VC++ 运行时(MSVCP140、VCRUNTIME140、VCRUNTIME140_1) | windows-x86_64 载荷从微软可再分发包(xlings-res/msvc 镜像,与 `xim:msvc` 14.44.35207 同一 vsix)取出 `Microsoft.VC143.CRT` 放入 `bin/`。windows-aarch64 暂缺镜像,列为后续项 | |
| 92 | +| macOS | 系统 framework 与 libc++ | 无新增 | |
| 93 | + |
| 94 | +- **新增 `xim:dbus` 1.16.2**:由 conda-forge 重新打包到 xlings-res/dbus(双端逐字节一致),依赖只有 libc 与 libpthread;构建 |
| 95 | + 前缀已重定位到 `/`。 |
| 96 | +- **后续项**:QtNetwork 所需的 krb5、brotli;windows-aarch64 的 CRT;xlings glibc 的 UTF-8 locale。 |
| 97 | + |
| 98 | +本机验证(手工模拟改写 RUNPATH):Linux 上 console、Widgets offscreen 两个程序均运行。Windows 的 CRT 放置由 CI 验证(V1)。 |
| 99 | + |
| 100 | +## 5. mcpp-deps:删除 |
| 101 | + |
| 102 | +它原是 deps 系列动作的命令,负责四件事: |
| 103 | +- vcpkg 的环境变量; |
| 104 | +- 安装根的锁; |
| 105 | +- 短路径的临时目录; |
| 106 | +- CMake 三步串联,以及解压前清空目录。 |
| 107 | + |
| 108 | +它经 `tools = ["mcpp-deps"]` 进入了消费方契约,也是 mcpp#705、#707 性能问题的来源。0.15.0 以不依赖新引擎能力的方式替代: |
| 109 | + |
| 110 | +| 职责 | 替代 | |
| 111 | +|---|---| |
| 112 | +| `VCPKG_ROOT`、`VCPKG_DISABLE_METRICS` | vcpkg 参数 `--vcpkg-root`、`--disable-metrics` | |
| 113 | +| 锁 | vcpkg 自身的 `<root>/vcpkg/vcpkg-running.lock`;workspace fixture 两成员共用一个根,本机通过(V2) | |
| 114 | +| 短路径临时目录 | `--x-buildtrees-root`、`--x-packages-root`、`--downloads-root`,路径在规划时计算 | |
| 115 | +| CMake 三步、清空并解压 | 构建程序写出的脚本,由 `cmake -P` 执行;参数以方括号参数书写,保留空格与分号 | |
| 116 | + |
| 117 | +- `tools/deps_main.cpp` 与 `[targets.mcpp-deps]` 直接删除,与 D1 的处理一致,不保留弃用目标。 |
| 118 | +- 依赖边写有 `tools = ["mcpp-deps"]` 的消费方须删除该项,这记入 §7。 |
| 119 | +- 本机 vcpkg-consumer、cmake-consumer、archive-consumer、vcpkg-workspace、vcpkg-libcxx 五个判据全部通过。 |
| 120 | + |
| 121 | +交给 mcpp 的只有通用能力,都不阻塞本版: |
| 122 | +- E1:动作支持环境变量与工作目录; |
| 123 | +- E2:feature 自带其所需的包内工具。`tools-embed` 的 `mcpp-embed` 仍经 `tools` 暴露,待 E2 支持后收回。 |
| 124 | + |
| 125 | +## 6. 规范与文档 |
| 126 | + |
| 127 | +- **README**:精简为约 100 行(原 1113 行),开篇陈述 §0 的总纲;各成员细节移至 `docs/<成员>.md`。 |
| 128 | +- **`docs/plugin-development.md`(新增)**:包含职责分层表和十条规则: |
| 129 | + 1. 机制而非策略; |
| 130 | + 2. feature 只表达机制; |
| 131 | + 3. build.mcpp 为先的三级配置; |
| 132 | + 4. 运行时闭包归载荷; |
| 133 | + 5. 内部实现不进入契约; |
| 134 | + 6. 工作即动作; |
| 135 | + 7. 缺失即警告; |
| 136 | + 8. 引擎缺口提交 issue; |
| 137 | + 9. 每条行为对应判据; |
| 138 | + 10. 文档简洁。 |
| 139 | + |
| 140 | + 第三方插件与项目内插件同样适用。 |
| 141 | + |
| 142 | +## 7. 兼容性(0.15.0 的破坏性变更) |
| 143 | + |
| 144 | +| 变化 | 消费方需做的修改 | |
| 145 | +|---|---| |
| 146 | +| 删除 `rules-qt-xim*` | 改为 `features = ["rules-qt"]`,并在 `[xlings]` 中声明 `xim:qt-base` 或 `xim:qt` 及版本 | |
| 147 | +| 删除 `mcpp-deps` | 从依赖边删除 `tools = ["mcpp-deps"]` | |
| 148 | +| vcpkg 前缀多一层 triplet | 改用返回的 `prefix`,不硬编码 `vcpkg_installed/<triplet>`(GalTranslPP `gpp.build` 第 182 行) | |
| 149 | +| 插件不再提供 glib 目录 | 使用外部 Qt 的 Linux 项目自行处理闭包 | |
| 150 | + |
| 151 | +以下变化不需要消费方修改:Linux 与 Windows 的 Qt 载荷会因 `installed()` 的标记 `runtime 1` 自动重装。 |
| 152 | + |
| 153 | +## 8. 任务依赖与 PR |
| 154 | + |
| 155 | +``` |
| 156 | +xlings-res/dbus(已发布) |
| 157 | +xim-pkgindex#885:dbus(单独拆出:CI 从已发布索引解析依赖,新包与其首个依赖方无法同时验证) |
| 158 | + │ 合入 → 索引发布 |
| 159 | +xim-pkgindex#884:qt、qt-base 的 Linux 闭包与 Windows CRT |
| 160 | + │ 合入 → 索引发布 |
| 161 | +mcpp-plugins#32 → 0.15.0(Linux Widgets 与 Windows CRT 判据依赖上一步) |
| 162 | + │ 三平台 CI 全绿 → tag、GitHub release、gtc 上传 GitCode |
| 163 | +mcpp-index:登记 0.15.0 |
| 164 | + │ |
| 165 | +GalTranslPP PR2:按 §7 迁移;Windows 回归(含 VC++ 运行时) |
| 166 | +并行:mcpp issue E1、E2 |
| 167 | +``` |
| 168 | + |
| 169 | +## 9. 总体评审 |
| 170 | + |
| 171 | +| 维度 | 结论 | |
| 172 | +|---|---| |
| 173 | +| 架构 | 四层职责不重叠;插件中的平台逻辑均由引擎提供的工具链信息推导,没有写死的值 | |
| 174 | +| 稳定性 | 动作的输入输出完整;运行时闭包在规划、链接、运行、打包阶段分别由引擎与载荷保证 | |
| 175 | +| 简洁 | 删除三个 feature、一个包内工具和 metadata 一级;新增的机制只有 `cmake -P` 脚本 | |
| 176 | +| 易用性 | 配置集中在 build.mcpp;依赖边不再有 `tools`;Qt 选择是两行显式声明 | |
| 177 | +| 兼容性 | 破坏性变更集中在 §7,每项修改为一到两行;载荷自动重装 | |
| 178 | +| 跨平台 | 三个平台的闭包逐一论证;windows-aarch64 的 CRT 为已知缺口 | |
| 179 | +| 一致性 | 三级配置、fact 记录、警告优先,对所有成员相同 | |
| 180 | +| 测试 | 新增 `qt-sdk-consumer`(三个层级)、Linux Widgets 与打包、Windows CRT、`vcpkg-libcxx` | |
| 181 | + |
| 182 | +遗留: |
| 183 | +- V1:Windows 的 CRT 是否被引擎放置到程序旁; |
| 184 | +- 后续项:krb5、brotli、windows-aarch64 的 CRT、UTF-8 locale。 |
0 commit comments