Skip to content

Commit 088ec8a

Browse files
docs: fix broken references and align README/docs with what the index now holds
Link and path fixes: * `docs/04-schema-xpkg-extension.md` in the mcpp repo is a 404 and has no commit history — it never lived at that path. Three places pointed at it (README, docs/README, docs/repository-and-schema). Replaced with what is actually authoritative today: `mcpp xpkg parse`, which is the parser CI runs and which fails on unknown mcpp-segment keys rather than ignoring them, plus mcpp's docs/spec/ for semantics. * docs/package-types.md pointed at `pkgs/m/mcpplibs.xpkg.lua`, which does not exist; the file is `pkgs/x/xpkg.lua`. * `docs/spec/package-identity.md` read like a path in this repo. It is mcpp's, and is now a qualified link. Alignment. The shape catalogue listed four forms while the README example table had grown to ten rows, and README still advertised "四类". The three shapes the index actually grew are now documented, each with the reason it exists rather than just its shape: * E — generated config for a full-source build. Works because these upstreams compile unselected backends to empty TUs; generate only where upstream has a gap, and generate with this index's toolchain (a host `cc` once produced a curl config asserting ssize_t did not exist). * F — shared-library compat. `soname` is load-bearing when something else dlopens the library: SDL2 opens libvulkan.so.1 itself, and against a static loader an application ends up with two of them. Also why the declaration sits in the linux block — a shared target propagates -fPIC, which clang rejects for the msvc target. * G — host runtime adapter. Why it is needed at all (mcpp runs under its own glibc, so a bare-soname dlopen never searches the host path), plus the two traps: versioned sonames only, because runtime.library_dirs also lands on the link line (mcpp#304), and the closure has to be complete or the executable stops starting. Every relative link and heading anchor in README and docs/ re-checked against GitHub's slug rules, and every external link fetched: all resolve. Co-authored-by: SPeak Agent <248744407+speak-agent@users.noreply.github.com>
1 parent d7460ed commit 088ec8a

4 files changed

Lines changed: 66 additions & 7 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,11 @@ mcpp self config --mirror CN # 切换至国内镜像,默认使用 GLOBAL 上
6161

6262
细节文档位于 [`docs/`](docs/),供人工与 agent 共同使用:
6363

64-
- [库形态与描述符模板](docs/package-types.md):C 源码、header-only、模块、外部 Form-A 四类模板与样例
64+
- [库形态与描述符模板](docs/package-types.md):各类形态的描述符模板与样例,以及最小工程的写法
6565
- [CN 镜像闭环](docs/cn-mirror.md):`gtc` 与 gitcode 操作,以及无 `mcpp-res` 权限时的回退方案。
6666
- [仓库结构与 schema 与 CI](docs/repository-and-schema.md):字段速查、选跑机制与本地 lint。
67-
- 字段规范见 [mcpp 扩展字段文档](https://github.com/mcpp-community/mcpp/blob/main/docs/04-schema-xpkg-extension.md)
67+
- 字段的**权威判定**`mcpp xpkg parse`(CI 用的就是它:未知的 mcpp 段字段直接失败,而不是被静默忽略);
68+
语义与约束见 mcpp 仓的 [`docs/spec/`](https://github.com/mcpp-community/mcpp/tree/main/docs/spec)
6869

6970
> 提交 PR 后,`validate` 自动执行 lint 并按改动库选跑对应 workspace 成员(整个测试面是一个 mcpp
7071
> workspace,公开模块包 `imgui`/`ffmpeg`/`opencv`/`tinyhttps` 也是普通成员——`compat` 的重定向声明在

docs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@
1010
| [repository-and-schema.md](repository-and-schema.md) | 仓库布局、描述符 schema 速查、`validate.yml` CI 行为、本地 lint 复现、案例索引 |
1111

1212
> 包的字段规范(`mcpp = { … }` 扩展)以上游为准,见
13-
> [mcpp docs/04-schema-xpkg-extension.md](https://github.com/mcpp-community/mcpp/blob/main/docs/04-schema-xpkg-extension.md)
13+
> `mcpp xpkg parse`(CI 使用的同一个解析器),语义与约束见 mcpp 仓的 [`docs/spec/`](https://github.com/mcpp-community/mcpp/tree/main/docs/spec)

docs/package-types.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,19 @@
33
编写描述符前,应先判定库所属的形态,再选用对应模板。`mcpp = {}` 内的所有路径均为**相对 verdir 的 GLOB**:
44
前导 `*` 用于吸收 tarball 的 `<repo>-<tag>/` wrap 层;`*` 匹配单段,`**` 匹配跨段(例如 `*/blas/*.cpp` 合法)。
55

6-
四种形态的判定要点如下:
6+
A–D 是四种**基础**形态,先按它们判定;E–G 是在基础形态之上叠加的处理方式,按需组合。
77

88
| 形态 | 特征 | 样例 | 关键字段 |
99
|---|---|---|---|
1010
| **A. C 源码 compat** | 纯 C 或少量源码,用户 `#include <foo.h>` | `pkgs/c/compat.cjson.lua``compat.zlib.lua``compat.gtest.lua` | `sources``c_standard` |
1111
| **B. header-only** | 纯头文件,无需编译 | `pkgs/c/compat.eigen.lua``compat.opengl.lua``compat.khrplatform.lua` | `include_dirs` 与 anchor 源 |
1212
| **C. C++23 module** | 暴露 `import x.y;` | `pkgs/n/nlohmann.json.lua` | `modules``generated_files` 或源 `.cppm` |
1313
| **D. 外部 Form-A 模块仓** | 上游自带 mcpp 描述符,独立仓库 | `pkgs/i/imgui.lua``pkgs/m/mcpplibs.*` | `mcpp = "<repo 路径>"`(Form A) |
14+
| **E. 生成 config 的全源码直编** | 上游用 configure/CMake 生成配置头,此处以 `generated_files` 落一份快照 | `pkgs/c/compat.libpng.lua``compat.curl.lua``compat.sdl2.lua``compat.ffmpeg.lua` | `generated_files` + `include_dirs` |
15+
| **F. 共享库 compat** | 必须是**唯一**的那个 `.so`(会被第三方 `dlopen`) | `pkgs/c/compat.x11.lua` 等 X11 家族、`compat.vulkan.lua`(linux) | `targets = { kind = "shared", soname = … }` |
16+
| **G. 宿主运行时适配** | 驱动之类无法 vendor 的东西,只做符号链接农场 + 元数据 | `pkgs/c/compat.glx-runtime.lua``compat.vulkan-runtime.lua` | `runtime.library_dirs` / `capabilities` |
17+
18+
完整的样例索引见[根 README 的「参考示例」表](../README.md#参考示例lua-描述符)
1419

1520
A、B、C 三类共用的骨架(`package` 头与 `xpm`)如下:
1621

@@ -122,7 +127,60 @@ modules 冲突),应配合 `import std;`。
122127

123128
上游或独立仓库自带 mcpp 描述符,本仓仅充当指针:`mcpp = "<相对或远程路径>"`(Form A,而非内联的 Form B)。新增的
124129
独立库通常归属于另一仓库(如 `mcpplibs/imgui-m`),本仓只负责登记。写法可参照 `pkgs/i/imgui.lua`
125-
`pkgs/m/mcpplibs.xpkg.lua`
130+
`pkgs/x/xpkg.lua`
131+
132+
---
133+
134+
## E. 生成 config 的全源码直编(`compat.curl` / `compat.sdl2`)
135+
136+
上游用 configure 或 CMake 生成一份配置头,而本仓要的是「列出 .c 文件」。可行的前提是这类库把**未选中的后端
137+
编成空 TU**(curl 的 `vtls/gtls.c` 从头到尾是 `#ifdef USE_GNUTLS`,SDL 的 `src/video/windows/*.c` 同理),于是
138+
源码列表可以是朴素的 glob,配置全部落在一份 `generated_files` 快照里。
139+
140+
只在**上游有缺口的平台**生成:curl 签入了 `lib/config-win32.h`(Windows 无需生成),SDL 签入了
141+
`SDL_config_windows.h` / `SDL_config_macosx.h`(只有 linux 落到无用的 `SDL_config_minimal.h`)。生成时务必
142+
**本索引的工具链**跑 configure —— 用宿主 `cc` 生成的 curl 配置曾断言 `ssize_t` 不存在,导致 curl 编不过自己
143+
的配置。
144+
145+
## F. 共享库 compat(`compat.x11` 家族 / `compat.vulkan`)
146+
147+
当这个库会被第三方 `dlopen` 时,它必须是进程里**唯一**的那一个,静态链接会出问题。
148+
149+
```lua
150+
targets = { ["vulkan"] = { kind = "shared", soname = "libvulkan.so.1" } },
151+
```
152+
153+
`soname` 不是可选项:SDL2`SDL_CreateWindow(SDL_WINDOW_VULKAN)``dlopen("libvulkan.so.1")` 并用它解析
154+
surface 创建。若 loader 是静态的,应用最终会有两个 loader —— 自己那份建 instance,SDL 那份建 surface ——
155+
`createSurface` 拿到一个对方没见过的 instance 而失败。
156+
157+
声明位置也有讲究:`kind = "shared"` 会把 `-fPIC` 传播给消费者,而 clang 对 msvc 目标直接拒绝该选项。因此
158+
`compat.vulkan` 把它写在 **linux 块内**,Windows 走另一套(链接预生成的 import library)。平台块里的 `targets`
159+
会覆盖顶层声明,`compat.ffmpeg` 亦如此。
160+
161+
## G. 宿主运行时适配(`compat.glx-runtime` / `compat.vulkan-runtime`)
162+
163+
GPU 驱动无法打包 —— ICD 必须匹配机器上的内核驱动。本仓的既定立场是把它建模为**宿主能力**,而不是假装厂商
164+
驱动是可再分发的普通包(见 `.agents/docs/2026-06-03-gl-runtime-packages-plan.md`)。这类包不 vendor 任何东西,
165+
只做符号链接农场加元数据:
166+
167+
```lua
168+
runtime = {
169+
library_dirs = { "mcpp_generated/<name>/lib" },
170+
capabilities = { "vulkan.icd.driver" },
171+
},
172+
```
173+
174+
之所以需要它:mcpp 的产物跑在**自带的 glibc** 下(`interp` 指向 `xim-x-glibc`,rpath 只覆盖 mcpp 自己的树),
175+
因此裸 soname 的 `dlopen` 根本不搜索宿主库路径 —— loader 能找到全部 ICD manifest,却一个驱动都打不开。
176+
177+
两个反复踩到的细节:
178+
179+
- **农场里只放带版本号的 soname**(`lib*.so.*`)。`runtime.library_dirs` 同时进**链接行**,一个裸 `libxcb.so`
180+
会遮蔽本仓自己的 `compat.xcb`,链接报 `undefined reference to XauDisposeAuth`(mcpp#304)。带版本号的名字对
181+
链接器不可见,而恰好是 `dlopen` 要的。
182+
- **闭包必须完整**。农场里有 `libxcb.so.1` 却没有它依赖的 `libXau.so.6`,会遮蔽掉本来能解析的宿主副本,可执行
183+
文件直接起不来。
126184

127185
---
128186

docs/repository-and-schema.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ tools/compat-ffmpeg/ 等 compat 大包的描述符再生成流水线
3131
`/home/speak/workspace/github/mcpp-community/mcpp`)。`mcpp --version` 应与 CI 对齐;feature 与 glob 行为以
3232
`src/manifest.cppm``src/modgraph/scanner.cppm``src/build/prepare.cppm` 为准。
3333
- xpkg 扩展 schema(权威):
34-
https://github.com/mcpp-community/mcpp/blob/main/docs/04-schema-xpkg-extension.md(对应本仓 `.xpkgindex.json`
34+
https://github.com/mcpp-community/mcpp/tree/main/docs/spec(对应本仓 `.xpkgindex.json`
3535
“mcpp ext” 链接)。V1 xpkg spec 见 `d2learn/xim-pkgindex``docs/V1/xpackage-spec.md`(url-template 约在第 172 行)。
3636
- CN 镜像组织:gitcode `mcpp-res`
3737

@@ -41,7 +41,7 @@ tools/compat-ffmpeg/ 等 compat 大包的描述符再生成流水线
4141

4242
### 包身份:`(namespace, name)`
4343

44-
身份是二元组 —— **`namespace` 是点分层级路径,`name` 是单一原子段**。层级一律放 `namespace`(mcpp SPEC-001 §3.2,`docs/spec/package-identity.md`):
44+
身份是二元组 —— **`namespace` 是点分层级路径,`name` 是单一原子段**。层级一律放 `namespace`(mcpp SPEC-001 §3.2,见 mcpp 仓的 [`docs/spec/package-identity.md`](https://github.com/mcpp-community/mcpp/blob/main/docs/spec/package-identity.md)):
4545

4646
```lua
4747
namespace = "compat", name = "zlib" --

0 commit comments

Comments
 (0)