Skip to content

Commit 04701d5

Browse files
committed
docs: rewrite README/docs/skill in a formal declarative register
Rewrite all prose across README.md, docs/*, and the add-mcpp-index-package skill into declarative, academic-style Chinese: remove colloquial terms (一把梭 / 踩坑 / 丢给 / 硬凑 / 藏不住 …) and decorative emoji (⚠️✅❌📘✓), and reformulate fragments as complete declarative sentences. The red-flag table becomes a "错误做法 / 正确做法" table; section headings are normalized (e.g. "本地 lint 一把梭" → "本地 lint 复现(等价于 CI lint job)", "踩坑" → "注意事项", "CI 兜底" → "CI 保障"). Technical content, commands, code samples, and links are unchanged.
1 parent 73b5746 commit 04701d5

6 files changed

Lines changed: 293 additions & 240 deletions

File tree

.agents/skills/add-mcpp-index-package/SKILL.md

Lines changed: 110 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -3,82 +3,107 @@ name: add-mcpp-index-package
33
description: Use when adding a new third-party library/package to the mcpp-index repo — writing a pkgs/*/*.lua descriptor, setting up a GitCode CN mirror via gtc, adding a minimal example, and opening a green PR. Covers the four package shapes (C-source compat / header-only / C++23 module / external Form-A module repo), the GLOBAL+CN mirror table, lint rules, the feature (sources-only) gate, and local + CI verification.
44
---
55

6-
# 给 mcpp-index 新增一个库(SOP)
7-
8-
把一个上游库收录进 [`mcpp-index`](https://github.com/mcpplibs/mcpp-index) 的标准流程。产出 = 一个
9-
`pkgs/<x>/<name>.lua` 描述符 + GitCode CN 镜像 + `tests/examples/` 最小工程 + README 一行 + 设计文档,最终
10-
**本地实测绿 → 开 PR → CI 全绿 → 合并**(合并后 `publish-artifact.yml` 自动重发 index artifact)。
11-
12-
参考真实落地案例(逐字可抄):
13-
- `.agents/docs/2026-06-27-add-cjson-and-nlohmann-json-plan.md`(C 源码 compat + 模块库)
14-
- `.agents/docs/2026-06-28-add-eigen-plan.md`(header-only + source-gated `blas` feature)
15-
- 既有 PR:#48(cjson + nlohmann.json),#50(eigen)。
16-
17-
> 配套参考文件(在仓库 `docs/` 下,人/agent 共用,按需读):
18-
> - [docs/package-types.md](../../../docs/package-types.md) —— 四种库形态的描述符模板 + 真实样例路径
19-
> - [docs/cn-mirror.md](../../../docs/cn-mirror.md) —— gtc / gitcode CN 镜像闭环(含无 mcpp-res 权限的回退)
20-
> - [docs/repository-and-schema.md](../../../docs/repository-and-schema.md) —— 仓库结构、schema、CI、关键文件、踩坑清单
21-
22-
## 何时用 / 不用
23-
- ****:把一个新库(或新版本)加进 mcpp-index。两种来源都适用:
24-
- **(a) 第三方上游库** —— 自己没有 mcpp 支持(如 cJSON / Eigen / nlohmann),由本仓以 `compat` 形态适配。
25-
- **(b) 用户基于 mcpp 开发的库** —— 上游已经是 mcpp 工程(自带 `mcpp.toml``mcpp emit xpkg` 产出描述符、自有 release),
26-
要登记进索引(如 `mcpplibs.*``tensorvia-cpu`)。这类多是 **Form A**:描述符只声明元数据 + 下载地址,无需内联构建。
27-
- **不用**:改 mcpp 本体、改 xlings 引擎、纯文档。那些不在本仓。
28-
29-
## 总流程(12 步)
30-
31-
按顺序做;每步的细节进对应参考文件。建议用 todo 跟踪。
32-
33-
1. **调研来源与形态**(最关键,决定模板)
34-
- **先分清来源**:是 (a) 第三方上游库,还是 (b) 用户自己的 mcpp 库?
35-
- (b) 自有 mcpp 库:形态已定(Form A,模块库),版本/release 上游已有 → 本步很轻,直接拿上游 `mcpp emit xpkg` 的描述符
36-
或照 `pkgs/t/tensorvia-cpu.lua` 写;重点落在镜像 + 登记 + 验证。
37-
- (a) 第三方库:需判形态(下面)。
38-
- 上游仓库、**最新 tag/版本**(`git ls-remote --tags <repo>``sort -V | tail`;注意大版本跳跃,如 Eigen 3.4 → 5.x)。
39-
- License、源码布局:下 tarball,`tar -tzf` 看顶层 wrap 目录 + 子目录;判断是
40-
**纯头 / C 源码 / 自带 `.cppm` 模块 / 有可选组件(可做 feature)**
41-
-`sha256sum`,并**复算两次确认稳定**(GitLab/部分归档会重新打包导致 sha 漂移 → CI 用 GLOBAL 拉取会校验失败)。
42-
2. **定形态 → 选模板**:见 [docs/package-types.md](../../../docs/package-types.md)。四类:C-source compat / header-only / C++23 module(generated wrapper)/ 外部 Form-A 模块仓。
43-
3. **建 CN 镜像**:`gtc` 在 gitcode `mcpp-res` org 下建仓 + 发 release,上传**与 GLOBAL 同一个 tarball**(保证 byte-identical → 同 sha)。**没有 `mcpp-res` 写权限时**:不要写镜像表,直接用 plain-string `url = "<GLOBAL 上游 release>"`(lint 允许;CN 用户回落上游),留给维护者后补镜像 —— 详见 [docs/cn-mirror.md](../../../docs/cn-mirror.md)
44-
4. **写描述符** `pkgs/<x>/<name>.lua`
45-
- ⚠️ **目录 `<x>` = 完整包名首字母**(`compat.eigen``pkgs/c/`,`nlohmann.json``pkgs/n/`),**不是短名**。放错本地 path index 会 `not found in local index`
46-
- 三平台 `xpm`(linux/macosx/windows),每个版本 `url = { GLOBAL=…, CN=… }` + `sha256`
47-
- 版本号写**裸版本**(`"1.2.3"`,不带前导 `v`);下载 URL 里可保留上游 `…/v1.2.3.tar.gz`
48-
5. **识别可门控的可选组件 → feature**(见下"feature 机制")。只能门控 **sources**
49-
6. **最小工程** `tests/examples/<short>/`(`short` = 包名去 `compat.`/`mcpplibs.` 前缀)
50-
- `mcpp.toml`(`[indices].compat = { path = "../../.." }` 指回仓根)+ 一个 `src/main.*`,做一个**会失败的真断言**(`return ok?0:1`)。
51-
- 若要测 feature:依赖写长式 `name = { version = "…", features = ["…"] }`
52-
7. **本地实测**(用与 CI 同版本的 mcpp):见下"本地验证"。必须真跑过 `mcpp build && mcpp run` 绿。
53-
8. **README** 在对应表(mcpplibs 模块库 / 独立模块库 / 第三方 C/C++ 库)加一行。
54-
9. **设计文档** `.agents/docs/<YYYY-MM-DD>-add-<lib>-plan.md`,记录形态判断、镜像、feature 评估、实测结论、踩坑。
55-
10. **本地 lint**:模拟 `validate.yml` 的 lint(语法 / 必填字段 / 无前导 v / mirror 检查)。见 [docs/repository-and-schema.md](../../../docs/repository-and-schema.md)
56-
11. **分支 → commit → push → PR**(从 `main` 切新分支;别直接推 main)。PR 描述写清形态、镜像、feature、实测。
57-
12. **盯 CI 绿**:`detect` 应只选中本库的 example(`smoke-full-linux`/`portable` 显示 `skipping`),`smoke-examples (<short>)` 绿;`mirror-cn-reachable` 覆盖新 CN url。合并交维护者。
58-
59-
## feature 机制(务必读准)
60-
61-
mcpp **0.0.68** 的包描述符 `features`**只能门控 `sources`**(其它子字段被 skip;源码核实见 `manifest.cppm` 的 features 解析)。
6+
# 向 mcpp-index 新增一个库(标准作业流程)
7+
8+
本文件定义将上游库收录进 [`mcpp-index`](https://github.com/mcpplibs/mcpp-index) 的标准流程。其产出包括:一个
9+
`pkgs/<x>/<name>.lua` 描述符、一个 GitCode CN 镜像、一个位于 `tests/examples/` 的最小工程、一条 README 记录,
10+
以及一份设计文档。完整流程为:本地验证通过,提交 PR,CI 全部通过,由维护者合并。合并后,`publish-artifact.yml`
11+
将自动重新发布 index artifact。
12+
13+
可直接参考的既有案例如下:
14+
15+
- `.agents/docs/2026-06-27-add-cjson-and-nlohmann-json-plan.md`(C 源码 compat 与模块库)。
16+
- `.agents/docs/2026-06-28-add-eigen-plan.md`(header-only 库及 source-gated `blas` feature)。
17+
- 既有 PR:#48(cjson 与 nlohmann.json)、#50(eigen)。
18+
19+
配套参考文档位于仓库 `docs/` 目录,供人工与 agent 共同使用,可按需查阅:
20+
21+
- [docs/package-types.md](../../../docs/package-types.md) —— 四种库形态的描述符模板与样例路径。
22+
- [docs/cn-mirror.md](../../../docs/cn-mirror.md) —— CN 镜像闭环,含无 `mcpp-res` 权限时的回退方案。
23+
- [docs/repository-and-schema.md](../../../docs/repository-and-schema.md) —— 仓库结构、schema、CI 行为、关键文件与注意事项。
24+
25+
## 适用范围
26+
27+
本流程适用于将一个新库(或库的新版本)加入 mcpp-index。被收录的库有两种来源,均适用本流程:
28+
29+
- **(a) 第三方上游库**:其上游自身不提供 mcpp 支持(如 cJSON、Eigen、nlohmann),由本仓以 `compat` 形态适配。
30+
- **(b) 基于 mcpp 开发的库**:其上游已是 mcpp 工程(自带 `mcpp.toml`,可由 `mcpp emit xpkg` 产出描述符,且具备自有
31+
release),仅需登记进索引(如 `mcpplibs.*``tensorvia-cpu`)。此类库通常采用 **Form A**,描述符只声明元数据与
32+
下载地址,无需内联构建信息。
33+
34+
本流程不适用于修改 mcpp 本体、修改 xlings 引擎或纯文档变更,上述内容不在本仓范围内。
35+
36+
## 总流程(十二步)
37+
38+
各步骤应按顺序执行,每一步的细节见对应参考文档。建议以 todo 跟踪进度。
39+
40+
1. **调研来源与形态**(决定模板,为最关键步骤)。
41+
- 首先判定来源:属于 (a) 第三方上游库,还是 (b) 基于 mcpp 开发的库。
42+
- 对 (b),形态已确定(Form A 模块库),版本与 release 由上游提供,因此本步骤较为简单:可直接采用上游
43+
`mcpp emit xpkg` 的描述符,或参照 `pkgs/t/tensorvia-cpu.lua` 编写;工作重心在镜像、登记与验证。
44+
- 对 (a),需按下文判定形态。
45+
- 确定上游仓库与**最新 tag/版本**(`git ls-remote --tags <repo>` 配合 `sort -V | tail`;须注意大版本跳跃,
46+
如 Eigen 由 3.4 跃迁至 5.x)。
47+
- 确认 License 与源码布局:下载 tarball,以 `tar -tzf` 查看顶层 wrap 目录与子目录,据此判定其属于
48+
**纯头文件 / C 源码 / 自带 `.cppm` 模块 / 含可选组件(可实现 feature)** 中的何种形态。
49+
- 计算 `sha256sum`,并**重复计算两次以确认稳定**。GitLab 等部分归档源会重新打包,导致 sha 漂移,进而使 CI
50+
经 GLOBAL 拉取时校验失败。
51+
2. **确定形态并选择模板**:详见 [docs/package-types.md](../../../docs/package-types.md)。四类形态为:C 源码 compat、
52+
header-only、C++23 module(generated wrapper)、外部 Form-A 模块仓。
53+
3. **建立 CN 镜像**:使用 `gtc` 在 gitcode `mcpp-res` 组织下建仓并发布 release,上传**与 GLOBAL 相同的 tarball**,
54+
以保证字节一致(sha 相同)。**在不具备 `mcpp-res` 写权限时**,不应构造镜像表,而应使用纯字符串形式
55+
`url = "<GLOBAL 上游 release>"`(lint 允许此形式,CN 用户将回退至上游源),镜像由维护者后续补充。详见
56+
[docs/cn-mirror.md](../../../docs/cn-mirror.md)
57+
4. **编写描述符** `pkgs/<x>/<name>.lua`
58+
- 目录 `<x>` **取完整包名首字母**(`compat.eigen` 对应 `pkgs/c/`,`nlohmann.json` 对应 `pkgs/n/`),
59+
而非短名。放置错误将导致本地 path index 报 `not found in local index`
60+
- `xpm` 须覆盖三平台(linux/macosx/windows),每个版本包含 `url = { GLOBAL=…, CN=… }``sha256`
61+
- 版本号采用**裸版本**(如 `"1.2.3"`),不含前导 `v`;下载 URL 中可保留上游的 `…/v1.2.3.tar.gz` 形式。
62+
5. **识别可门控的可选组件并实现 feature**(参见下文“feature 机制”)。feature 仅能门控 **sources**
63+
6. **编写最小工程** `tests/examples/<short>/`(`short` 为包名去除 `compat.`/`mcpplibs.` 前缀后的结果)。
64+
- 包含 `mcpp.toml`(其 `[indices].compat = { path = "../../.." }` 指回仓根)与一个 `src/main.*`,
65+
后者须包含**可失败的有效断言**(`return ok ? 0 : 1`)。
66+
- 如需测试 feature,依赖采用长式声明 `name = { version = "…", features = ["…"] }`
67+
7. **本地验证**(使用与 CI 相同版本的 mcpp,详见下文“本地验证”)。必须实际执行 `mcpp build``mcpp run` 并通过。
68+
8. **更新 README**:在对应分类表中新增一条记录。
69+
9. **撰写设计文档** `.agents/docs/<YYYY-MM-DD>-add-<lib>-plan.md`,记录形态判定、镜像、feature 评估、验证结论
70+
与注意事项。
71+
10. **本地 lint**:在本地复现 `validate.yml` 的 lint 检查(语法、必填字段、无前导 v、镜像表校验)。详见
72+
[docs/repository-and-schema.md](../../../docs/repository-and-schema.md)
73+
11. **提交变更**:由 `main` 切出新分支,依次 commit、push、开 PR(不应直接推送 `main`)。PR 描述应载明形态、镜像、
74+
feature 与验证结论。
75+
12. **确认 CI 通过**:`detect` 应仅选中本库对应的 example(`smoke-full-linux``smoke-portable` 显示 `skipping`),
76+
`smoke-examples (<short>)` 通过,`mirror-cn-reachable` 覆盖新增 CN url。合并由维护者执行。
77+
78+
## feature 机制
79+
80+
mcpp **0.0.68** 的包描述符 `features`**仅能门控 `sources`**;其余子字段会被解析器忽略(经 `manifest.cppm`
81+
features 解析逻辑确认)。
6282

6383
```lua
6484
mcpp = {
65-
sources = { "*/core.c" }, -- 默认总编
85+
sources = { "*/core.c" }, -- 默认始终编译
6686
features = {
67-
["extra"] = { sources = { "*/extra.c" } }, -- 默认排除;features=["extra"] 时编入同一个 lib 目标
87+
["extra"] = { sources = { "*/extra.c" } }, -- 默认排除;请求 features=["extra"] 时编入同一 lib 目标
6888
},
6989
}
7090
```
71-
- 消费侧:`dep = { version = "…", features = ["extra"] }`
72-
- 真实例:`compat.gtest``main`(gtest_main.cc)、`compat.cjson``utils`(cJSON_Utils.c)、`compat.eigen``blas`(`*/blas/*.cpp` + `*/blas/f2c/*.c`)。
73-
- **判定"可不可以做 feature"**:这个可选组件是不是**额外的可编译源码**?是 → 能门控。
74-
纯头(如 Eigen `unsupported/`,与核共享 include 根,藏不住)→ 不能。
75-
编译 **define**(如 `EIGEN_MPL2_ONLY``EIGEN_USE_BLAS`)→ 当前 feature 表带不了 → 不能(留注释,待 mcpp 支持 define/cflags)。
76-
- **glob**:支持 `*`(段内)与 `**`(跨段),所以 `*/blas/*.cpp``*/foo/**/*.c` 都行。
77-
- **必须做负向验证**:不带 feature 时那个符号/源应**确实缺失**(链接 `undefined reference` 或编译找不到),证明门控真生效——不是默认就编进去了。
91+
92+
- 消费侧声明:`dep = { version = "…", features = ["extra"] }`
93+
- 既有实例:`compat.gtest``main`(gtest_main.cc)、`compat.cjson``utils`(cJSON_Utils.c)、`compat.eigen`
94+
`blas`(`*/blas/*.cpp``*/blas/f2c/*.c`)。
95+
- 判定某可选组件能否实现为 feature 的准则:该组件是否为**额外的可编译源码**。若是,则可门控。纯头文件(如 Eigen 的
96+
`unsupported/`,与核心共享 include 根,无法隐藏)不可门控;编译期 **define**(如 `EIGEN_MPL2_ONLY`
97+
`EIGEN_USE_BLAS`)当前无法由 feature 表携带,因而不可门控,应在描述符中加注释说明,待 mcpp 支持 define/cflags
98+
后再实现。
99+
- glob 规则:支持 `*`(段内匹配)与 `**`(跨段匹配),因此 `*/blas/*.cpp``*/foo/**/*.c` 均合法。
100+
- **须进行负向验证**:在不启用 feature 时,对应的符号或源码应**确实缺失**(表现为链接期 `undefined reference`
101+
或编译期找不到),以此证明门控确实生效,而非默认即被编入。
78102

79103
## 本地验证(与 CI 同版本)
80104

81-
CI 的 mcpp 版本 = `.github/workflows/validate.yml``env.MCPP_VERSION`**用同一版本本地跑**,别用恰好装着的旧版。
105+
CI 所用 mcpp 版本由 `.github/workflows/validate.yml``env.MCPP_VERSION` 指定。本地验证应使用同一版本,而非本地
106+
恰好安装的其它版本。
82107

83108
```bash
84109
MV=$(grep -oP 'MCPP_VERSION:\s*"\K[0-9.]+' .github/workflows/validate.yml)
@@ -88,20 +113,24 @@ root="$PWD/mcpp-$MV-linux-x86_64"
88113
mkdir -p ~/.mcpp/registry && cp -a "$root/registry/." ~/.mcpp/registry/
89114
export MCPP="$root/bin/mcpp"
90115
export MCPP_VENDORED_XLINGS="$root/registry/bin/xlings"
91-
export MCPP_INDEX_MIRROR=GLOBAL # CI example GLOBAL;CN 由 mirror-cn-reachable 单独兜
116+
export MCPP_INDEX_MIRROR=GLOBAL # CI example 使用 GLOBAL;CN 由 mirror-cn-reachable 单独校验
92117
MCPP="$MCPP" bash tests/run_example.sh <short>
93118
```
94-
- 输出末尾要有你的断言行 + `OK: <short>`
95-
- run_example.sh 会 `rm -rf target .mcpp` 从干净态走真实管线(fetch→generate→compile→link→run)。
96-
- 想直接看头/源:解包在 `tests/examples/<short>/.mcpp/.xlings/data/xpkgs/<idx>-x-<name>/<ver>/<wrap>/`
97-
98-
## 红线 / 常见错误
99-
100-
- ❌ 把 `compat.foo.lua` 放进 `pkgs/f/`。✅ 放 `pkgs/c/`(完整名首字母)。
101-
- ❌ 版本写 `"v1.2.3"`。✅ 裸 `"1.2.3"`(lint 会拦前导 v)。
102-
- ❌ CN 镜像传了"加工过"的包(≠ GLOBAL)。✅ 传 GLOBAL 同一个 tarball,sha 一致;否则破坏 GLOBAL/CN 一致性。
103-
- ❌ 只 `mcpp build``run`,或例子里没有真断言。✅ 真跑 + `return ok?0:1`
104-
- ❌ 宣称"做了 feature"却没负向验证。✅ 证明默认确实不含。
105-
- ❌ 没对齐 CI 的 mcpp 版本,本地绿 CI 红。✅ 读 `MCPP_VERSION`
106-
- ❌ 直接 push `main`。✅ 切分支开 PR。
107-
- 完成前遵循 `verification-before-completion`:**贴出真实命令输出**再说"绿/完成",不要凭感觉。
119+
120+
- 输出末尾应包含断言行与 `OK: <short>`
121+
- `run_example.sh` 会执行 `rm -rf target .mcpp`,自干净状态走完整管线(fetch、generate、compile、link、run)。
122+
- 如需查看头文件或源码,解包结果位于 `tests/examples/<short>/.mcpp/.xlings/data/xpkgs/<idx>-x-<name>/<ver>/<wrap>/`
123+
124+
## 常见错误与规避
125+
126+
| 错误做法 | 正确做法 |
127+
|----------|----------|
128+
|`compat.foo.lua` 置于 `pkgs/f/` | 置于 `pkgs/c/`,目录取完整包名首字母 |
129+
| 版本写作 `"v1.2.3"` | 采用裸版本 `"1.2.3"`,lint 会拦截前导 v |
130+
| CN 镜像上传经改动的包(与 GLOBAL 不一致) | 上传与 GLOBAL 相同的 tarball,sha 一致,以维持 GLOBAL/CN 一致性 |
131+
| 仅执行 `mcpp build` 而不 `run`,或示例缺少有效断言 | 实际运行,并以 `return ok ? 0 : 1` 断言 |
132+
| 声称实现了 feature 却未做负向验证 | 验证默认构建确实不含该组件 |
133+
| 未对齐 CI 的 mcpp 版本,本地通过而 CI 失败 | 读取 `MCPP_VERSION` 并使用同一版本 |
134+
| 直接推送 `main` | 切出分支并提交 PR |
135+
136+
完成前应遵循 `verification-before-completion`:在声明“通过/完成”之前,须给出真实命令输出作为证据。

0 commit comments

Comments
 (0)