From dfe3d71b4457473b8c6ada52195e5dcd869148da Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sat, 24 Oct 2026 03:28:50 +0900 Subject: [PATCH 01/51] docs: checkpoint the mwrap implementation and template contract --- ...24-mwrap-repository-and-module-standard.md | 269 ++++++++++ ...0-24-opencv-5-full-and-onnxruntime-plan.md | 485 ++++++++++++++++++ 2 files changed, 754 insertions(+) create mode 100644 .agents/docs/2026-10-24-mwrap-repository-and-module-standard.md create mode 100644 .agents/docs/2026-10-24-opencv-5-full-and-onnxruntime-plan.md diff --git a/.agents/docs/2026-10-24-mwrap-repository-and-module-standard.md b/.agents/docs/2026-10-24-mwrap-repository-and-module-standard.md new file mode 100644 index 0000000..f766573 --- /dev/null +++ b/.agents/docs/2026-10-24-mwrap-repository-and-module-standard.md @@ -0,0 +1,269 @@ +# mwrap 仓库、包与模块设计规范(评审稿) + +状态:Draft,等待用户 review。日期:2026-10-24。 + +本轮只新增设计文档。组织 fork、创建仓库、改名、功能重构、发布和索引迁移均在评审后实施。 +配套方案:[OpenCV 与 ORT 实施设计](2026-10-24-opencv-5-full-and-onnxruntime-plan.md)。 + +## 1. 定位与边界 + +`mcpplibs` 顶层承载原生 C++ 模块项目;`mcpplibs.mwrap` 承载对已有 C/C++ 头文件库的模块化封装。 +`mwrap` = module wrapper,统一替代本类新项目的 `capi`、`cppapi` 分类。既有包按迁移计划逐个处理,不批量改写已发布版本。 + +共同契约:保留上游公共实体、namespace、类型身份、调用方式与语义,增加命名模块入口。 +模块化无法原样携带的内容必须单独列出:宏、内部链接实体、依赖预处理配置的接口和 ABI 配置。 +不以“编译成功”代替公共 API 覆盖,也不将已声明的后端枚举当作可用实现。 + +## 2. 命名规则 + +| 层次 | 规则 | OpenCV | ONNX Runtime | +|---|---|---|---| +| Git 仓库 | `-m` | `mcpplibs/opencv-m` | `mcpplibs/onnxruntime-m` | +| package.namespace | `mcpplibs.mwrap` | 同左 | 同左 | +| package.name | 单个原子名称,无 `-m` 后缀 | `opencv` | `onnxruntime` | +| 完整包身份 | namespace + name | `mcpplibs.mwrap.opencv` | `mcpplibs.mwrap.onnxruntime` | +| 根模块 | 同完整包身份 | `mcpplibs.mwrap.opencv` | `mcpplibs.mwrap.onnxruntime` | +| 公共子模块 | 保留上游模块/头文件分组名称 | `mcpplibs.mwrap.opencv.core` | 有实际接口边界再增加 | +| API namespace | 保留上游 | `cv::`、`cv::dnn::` | `Ort::`;C API 保持全局名称 | +| 宏映射模块 | `.macros` | `mcpplibs.mwrap.opencv.macros` | `mcpplibs.mwrap.onnxruntime.macros` | + +上游名称中不能用于模块标识符的字符使用稳定、可记录的规范化映射;不因仓库改名改变 API namespace。 +不创造 `mcpplibs::mwrap::opencv::Mat` 等替代 API,不主动将 C 全局函数搬入 namespace。 +不按 CUDA、GTK、ORT 等实现后端增加公共 API 模块,除非上游本身有可独立消费的接口。 + +```toml +[package] +namespace = "mcpplibs.mwrap" +name = "opencv" +version = "5.0.0" # 与上游对齐;封装修订依次为 5.0.0.1、5.0.0.2 + +[package.metadata.mwrap] +upstream-version = "5.0.0" +``` + +```toml +# 消费端 +[dependencies."mcpplibs.mwrap"] +opencv = { version = "5.0.0", features = ["imgproc", "imgcodecs-png", "highgui-native", "dnn-onnxruntime"] } +``` + +以上 metadata 为本规范自定义记录,mcpp 不会替我们解释 `upstream-version`。 +namespace 是多段路径、name 是单段名称,遵守 mcpp 的包身份规则。 + +## 3. 仓库范式:封装与上游分离 + +```text +-m/ +├── mcpp.toml # 封装包身份、features、依赖、targets +├── build.mcpp # 按需生成配置、派生 TU 和资源 +├── .xlings.json # 固定经过验证的最新稳定 mcpp +├── upstream/ +│ ├── sources.lock.toml # 来源、tag/commit、归档 SHA256、许可证 +│ ├── README.md # 获取/导入/更新流程,裁剪规则 +│ └── / # vendored 原始源码(仅需要时存在) +├── patches/ +│ ├── series # 有序补丁;没有补丁也明确记录 +│ └── README.md # 原因、影响、上游 issue、移除条件 +├── port/ +│ ├── include/ # 适配头、宏兼容头 +│ ├── src/ # 必需的替换实现和平台适配 +│ └── config/ # 配置模板、模块与后端依赖清单 +├── src/ +│ ├── .cppm # 公共根模块,满足 mcpp lib-root 约定 +│ ├── macros.cppm +│ └── modules/ # 公共子模块与必要的内部 partition +├── generated/ # 可复现、确有必要提交的稳定生成物 +├── tools/ # 同步、生成、公共 API 审计工具 +├── tests/ +│ ├── surface/ # 导出、类型身份、宏等价性 +│ ├── behavior/ # 真实功能 +│ └── consumers/ # 头文件混用、模块共存、安装后消费 +├── examples/ +├── docs/ +└── .agents/docs/ +``` + +`tests/` 的子目录是本规范布局;须由测试 targets 或受控发现规则接入,不假定目录移动后 mcpp 自动执行全部测试。 +构建期、按 feature 变化的文件进入 mcpp 输出目录;不能写回共享 `generated/` 或修改 `upstream/`。 +公开头文件通过 include_dirs 暴露;上游内部头与生成配置保持私有,确有消费者需求的配置另行定义契约。 + +参考 openkal-musl 的实质是三种内容分离:`musl/`(上游)、`port/`(适配)、`musl-generated/`(可复现生成物), +以及修改/排除理由可追溯。这里统一到 `upstream/`,不照搬它的 libc 移植语义。 + +## 4. 上游实现的三条接入路线 + +| 路线 | 使用条件 | 要求 | +|---|---|---| +| `compat.` | 已有可复用的传统库包,配置和 ABI 足够 | 封装仅依赖它,不复制源码/二进制,不重复编译实现 | +| vendor 到 `upstream//` | 复杂配置、SIMD、生成代码、平台后端需要本仓库组织 | 固定来源和裁剪清单,源码与 port 分离,所有修改可审计 | +| 预编译 SDK | 上游构建复杂且官方有合适 SDK,如首版 ORT | 平台/ABI/provider/运行库清单、hash 和许可明确;不承诺无产物目标可用 | + +`compat` 是传统实现供应者,`mwrap` 是模块接口供应者。一个程序中的同一实现必须只有一个所有者。 +不为了形式统一强制新增 `compat.opencv`;当前复杂的 OpenCV 构建可保留源码所有权。 +不将 build.mcpp 变成下载器,依赖获取由包/索引/provider 管理;源码预处理通过有输入输出的 action 表达。 +若依赖 CMake,在 CI 构建包时或明确声明的构建步骤中使用,必须说明与“消费端无需 CMake”的区别。 + +## 5. 模块与导出契约 + +1. 封装层优先使用上游实体的 `export using`;不复制公共类或重新定义同名类型。 +2. 每个实体有一个导出归属,根模块 `export import` 当前启用的公共模块。 +3. 子模块可单独 import,并能组合 import;不通过偶然的传递头文件获得未声明能力。 +4. root 与可选模块闭包由模块清单生成,打包后的公共模块集合与源码消费一致。 +5. `static inline` 等确需替换时,记录单独清单;验证语义、ADL、重载与头文件混用,不默默裁剪。 +6. 审计范围取上游公共 C/C++ 头文件,Python 绑定标记只能作为生成器输入之一。 +7. 内部实现使用 partition 或未公开模块;根模块不能意外把内部接口带入发布闭包。 + +## 6. 宏的模块化映射 + +`.macros` 是命名模块,不是预处理器宏的传输通道。 +推荐映射 namespace:`mcpplibs::mwrap::::macros`,保留宏的原始名称。 +宏映射是有意新增的 API 面,与保持上游 namespace 的普通实体分开管理。 + +```cpp +import mcpplibs.mwrap.opencv; +import mcpplibs.mwrap.opencv.macros; +namespace ocvm = mcpplibs::mwrap::opencv::macros; + +cv::Mat image(64, 64, ocvm::CV_8UC3); +static_assert(ocvm::CV_MAKETYPE(ocvm::CV_8U, 3) == ocvm::CV_8UC3); +``` + +| 上游宏种类 | 映射方式 | +|---|---| +| 数值、字符串等对象式宏 | 类型明确的 inline constexpr;先在 GMF 中捕获值,再 undef,避免声明被展开 | +| 可保持语义的计算宏 | constexpr 函数,记录整数提升、求值次数、返回类型等差异 | +| `#if`、token 拼接、字符串化、注解/导出属性 | 兼容头文件保留原始宏 | +| 断言/日志/控制流宏 | 默认保留宏;只有调用位置、求值和控制流契约可证明时才增加具名辅助函数 | + +不承诺所有宏都可映射;尤其普通函数不能自动保留 CV_Assert 的表达式字符串化与调用点信息。 +兼容头建议 `/macros.hpp>`,在 import 前包含。测试对象式宏存在时对 qualified 名字的展开冲突; +不能认为加 namespace 就能规避预处理器。文档分别展示纯模块映射用法与原始宏用法,避免同一 TU 直接混用冲突名称。 +旧 `cv::CV_*` 常量属于已有封装扩展,迁入新包时转到 `.macros`;旧身份冻结兼容,不继续向上游 namespace 添加宏替身。 + +## 7. feature、平台和运行时 + +使用 mcpp 的 implies、forward、feature-deps、cfg(target) 和 build.mcpp action。 +feature 表达增加能力,依赖图同一包的请求取并集;不能设计靠依赖路径获得不同 ABI 的相反配置。 +仅需启用的外部库放 `[feature-deps.]`,链接参数由实现供应者携带。 +真正互斥的供应者通过明确变体/依赖图约束处理;capability 可以做选择,但不会移除其他已引入包的对象文件, +也不会自动发现 SDK 或保证兼容。同名符号的两份运行库必须在进入最终链接图前避免同时引入。 + +### 7.1 feature 命名规范 + +feature 使用小写 kebab-case,优先复用上游模块、后端、依赖的正式名称。 + +| 类别 | 规则 | 示例 | +|---|---|---| +| 上游模块 | `` | dnn、highgui、videoio、stitching | +| 模块的后端/可选依赖 | `-` | highgui-gtk3、videoio-ffmpeg、dnn-onnxruntime | +| 模块的图像格式 | `imgcodecs-` | imgcodecs-jpeg、imgcodecs-tiff | +| 跨模块加速依赖 | 使用正式名称 | opencl、tbb、ipp、lapack | +| contrib 模块 | `contrib-` | 以固定上游版本的实际模块名为准 | +| 模块全集 | `all-modules` | 仅表达主仓库模块集合,不承诺所有后端/SDK | + +不在公共接口混用 gui/highgui、codec/imgcodecs、ort/onnxruntime;正式 feature 使用上游可识别名称。 +native 可作为有精确 target 映射表的便利开关,如 highgui-native;显式 backend 名仍保留。 +未支持的目标、缺失供应者和互斥后端组合在配置阶段给出明确错误,不静默忽略用户选择。 +default 的展开写入版本化清单;不把 desktop/full 等没有唯一含义的名称作为基础能力分类。 +当前 pinned mcpp 不支持消费者关闭依赖的 default features,因此默认集合应最小化,不能无条件绑定可替换后端或大体积 SDK。 +OpenCV 新包建议 default=[]、core 为必需基础,其余模块与实现显式启用;常用体验由模板列出所需 features。 +同名 feature 不得在不同修订中无说明地改成其他执行后端。 + +### 7.2 索引分类布局 + +描述符统一置于 `mcpp-index/pkgs/mwrap/.lua`,测试置于 `tests/mwrap/`。 +不再增加首字母子目录。Git 源码与发布归档保持同一布局,不生成到 pkgs/m 的转换副本。 +已核查 mcpp v2026.10.21.1:身份查找的 fallback 扫描 pkgs 下一级目录,子目录名不要求是单个字母; +因此 pkgs/mwrap 是与现有扫描深度相容的分类,根目录 mwrap/o 则不在该查找路径内。 +发布脚本原本复制整个 pkgs,可直接保留新目录;lint、测试选择器、站点和 provider 仍须做集成验证。 +即使部分脚本的 pkgs/*/*.lua glob 已能覆盖,也要核查是否存在目录名必须单字母的额外假设。 +不因包装层分类而扩大客户端索引协议,也不为保持首字母分桶维护第二份 descriptor。 + +### 7.3 测试责任 + +Linux 优先本地执行,CI 重跑发布关键组合;Windows 与 macOS 由 CI 覆盖。 +CI 的编译、链接、功能执行和安装后消费分别报告;桌面/设备/GPU 不可用时明确未执行项。 +所有平台使用同一测试入口、feature 展开和固定工具版本,不能靠平台专属的临时脚本掩盖配方差异。 +设计文档检查与实现验证分别报告;本轮更新规范并不表示上述平台功能已通过运行验证。 + +配置身份至少覆盖 target triple、工具链/stdlib、linkage、feature 闭包、上游版本和适配补丁。 +公共布局、异常/RTTI、运行时、CPU baseline 必须一致;SIMD 编译选项限定在实现 TU,不污染公共 BMI。 +宿主工具和目标库分开;不以构建宿主 OS 替代目标平台判断。 +预编译库需要测试动态加载的 provider、数据和插件;它们未必出现在普通链接依赖扫描结果中。 + +### 7.4 每个 -m 库必须提供快捷模板 + +每个以 -m 命名并发布的模块封装库至少提供一个可运行的默认 mcpp 项目模板,位于 templates//。 +模板通过完整包身份调用,例如 `mcpp new vision --template mcpplibs.mwrap.opencv@5.0.0`。 +多个模板使用 `: