diff --git a/.agents/docs/2026-10-24-implementation-checkpoints.md b/.agents/docs/2026-10-24-implementation-checkpoints.md new file mode 100644 index 0000000..546da9c --- /dev/null +++ b/.agents/docs/2026-10-24-implementation-checkpoints.md @@ -0,0 +1,45 @@ +# OpenCV mwrap implementation checkpoints + +## Source/interface separation checkpoint + +- Fork exists at mcpplibs/opencv-m; implementation branch retains commits. +- Existing pinned upstream source moved to upstream/opencv without content changes. +- Generated snapshots moved to generated; compatibility header moved to port/include/mwrap/opencv. +- Root and submodule names changed to mcpplibs.mwrap.opencv; upstream cv API preserved. +- Macro constants moved from cv into mcpplibs::mwrap::opencv::macros. +- LLVM 23.1.3 baseline build passed (2747 units including the existing FFmpeg closure). +- Existing test suite: six binaries passed; DNN/unifont gated cases require their feature runs separately. +- Package revision 5.0.0.1 distinguishes this wrapper from the inherited v5.0.0 tag without changing upstream version. +- Remaining: source/feature catalog split, additional modules, native GUI, ORT bridge, codecs/backends, full API audit, native CI and installed/template consumers. + +## Optional source catalog checkpoint + +- Generated per-platform source catalogs separate mandatory core, optional modules, codecs and video backends. +- The root module aggregates only selected module interfaces; FFmpeg is a videoio-ffmpeg feature dependency. +- Build-instance configuration and build information reflect the chosen JPEG/PNG features. +- Linux LLVM 23.1.3 strict core-only and PNG/JPEG configurations passed all six test binaries. The image configuration executed both actual codec roundtrips; feature-disabled DNN/unifont binaries contain no cases and do not establish coverage for those capabilities. +- CI now runs image codec features separately from core-only and DNN/unifont configurations. +- mcpp engine is read-only. Its existing documentation/skill PR remains unmerged and is not a dependency of this work. +- Native GUI, remaining main modules and ORT bridge remain implementation work; this checkpoint does not claim full support. + +## Aggregate module CI correction + +- Run 40010892459 exposed imports introduced through a header: GCC rejected them, while Windows built the library but consumers could not see the aggregate's core API. +- The conventional src/opencv.cppm now directly re-exports core, macros and an internal selection module. +- build.mcpp writes that selection module into its configuration-specific output and declares it with mcpp::generated before scanning. The generated file contains concrete imports for the selected features, with no header-induced or preprocessor-conditional imports. +- Existing root-import API, header-mixing and codec tests exercise the aggregate from consumers; native Windows verification remains in CI. +- This correction requires no mcpp engine changes. + +## Windows checkout newline correction + +- Reproduced the Windows selection problem locally by feeding CRLF versions of the tracked configuration files to the real build program: selected.cppm incorrectly contained no optional module imports. +- Module and source catalog lines now strip CRLF carriage returns; cvconfig is normalized before optional codec definitions are disabled. +- tools/test_build_config.py executes the compiled build program against LF and CRLF fixtures and verifies identical selected modules, source directives and codec configuration. It passed locally and is included in the Linux GCC CI job. +- GCC 16 and musl static core-only tests passed, as did GCC 16 and LLVM 23 PNG/JPEG roundtrips after the aggregate correction. Windows core tests passed in run 40015097526; complete feature verification follows on the new CI head. + +## Executable quickstart and documentation checkpoint + +- tools/test_template.py invoked the actual mcpp installed-package template renderer, verified the qualified self.name/version dependency, then built and ran the generated candidate consumer under LLVM 23.1.3. It wrote a 64x64 out.png successfully. This is a staged-source template test, not a published archive installation test. +- Added this actual template flow to the Linux LLVM CI leg. +- English/Chinese README now describe current feature selection, module and macro names, verified coverage and unfinished native GUI/ORT/full-module work. Removed inherited full-featured claims and broken example links. +- Package metadata now agrees with the existing Apache-2.0 root LICENSE, without replacing or relicensing the existing license file. The image example explicitly selects required PNG/JPEG features. 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..0c906cb --- /dev/null +++ b/.agents/docs/2026-10-24-mwrap-repository-and-module-standard.md @@ -0,0 +1,280 @@ +# 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 等没有唯一含义的名称作为基础能力分类。 +已通过 E2E 126/127 核实:当前 pinned mcpp 支持依赖边的 default-features=false,显式 features 仍激活; +不支持的是根项目 --no-default-features CLI。其他依赖边仍可请求默认项。最小默认集合是本规范的产品选择,不是客户端限制。 +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`。 +多个模板使用 `: