Skip to content

Commit 75ebd91

Browse files
committed
compat.yaml-cpp 0.8.0 and 0.9.0, measured on openkal; the site's openkal facet names openkal-ecosystem and openkal-compat; a shorter README
compat.yaml-cpp builds upstream's CMake target as it is (src/*.cpp plus the contrib GraphBuilder), from the GitHub tag archives mirrored byte for byte to gitcode mcpp-res/yaml-cpp. YAML_CPP_STATIC_DEFINE, a PUBLIC definition of a static build upstream, reaches consumers through a yaml-cpp/dll.h shim, since descriptor `defines` stay package-private; the test asserts it at compile time. Each version has a member (yaml-cpp, yaml-cpp-v080), and both are measured on openkal. The test found an upstream defect: GraphBuilderInterface's pure virtual destructor is defined nowhere, so a derived class links only when its user defines it. The test does, as any consumer must; the descriptor does not. The site's openkal facet had three sentences for values (openkal itself / runs on openkal / fails on openkal). It now has two names: openkal-ecosystem for the packages that make up openkal, openkal-compat for packages measured to run in an openkal graph. A package that only builds or fails is filed under neither; its page still shows the per-target measurement. The README keeps one line per shape in its reference table; the long explanations for recastnavigation and huxerui move into the descriptor catalog, which gains a yaml-cpp row.
1 parent cf36e1e commit 75ebd91

16 files changed

Lines changed: 779 additions & 127 deletions

File tree

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# compat.yaml-cpp 0.8.0 / 0.9.0
2+
3+
## Shape
4+
5+
C++ source compat (Form B). Upstream's CMake target is `src/*.cpp` plus, with
6+
`YAML_CPP_BUILD_CONTRIB` at its default ON, `src/contrib/*.cpp`. No configure
7+
step, no generated header, no platform code in the library. 0.9.0 adds one TU
8+
(`src/fptostring.cpp`, over the vendored `src/contrib/dragonbox.h`) and one
9+
public header (`yaml-cpp/fptostring.h`); one glob covers both versions.
10+
11+
Tags are spelled differently upstream (`0.8.0`, `yaml-cpp-0.9.0`), so the wrap
12+
dirs differ (`yaml-cpp-0.8.0/`, `yaml-cpp-yaml-cpp-0.9.0/`); `*` absorbs both.
13+
14+
## Mirror
15+
16+
gitcode `mcpp-res/yaml-cpp`, releases `0.8.0` and `0.9.0`, assets byte-identical
17+
to the GitHub tag archives (sha256 checked after download from both sides; each
18+
GitHub archive downloaded twice, digest stable).
19+
20+
| version | sha256 |
21+
| --- | --- |
22+
| 0.8.0 | `fbe74bbdcee21d656715688706da3c8becfd946d92cd44705cc6098bb23b3a16` |
23+
| 0.9.0 | `25cb043240f828a8c51beb830569634bc7ac603978e0f69d6b63558dadefd49a` |
24+
25+
## YAML_CPP_STATIC_DEFINE
26+
27+
Upstream makes it a PUBLIC definition of a static build and reads it only in
28+
`include/yaml-cpp/dll.h`, which every public header reaches. A descriptor's
29+
`defines` are package-private, so `mcpp_generated/yaml-cpp/dll.h` defines it
30+
and `#include_next`s upstream's; `mcpp_generated` is first in `include_dirs`.
31+
The compile database confirms the consumer TU carries no `-D` for it, and the
32+
test's `#error` guard passes: the shim delivered it.
33+
34+
## Upstream defect found by the test
35+
36+
`GraphBuilderInterface` declares its destructor pure virtual and defines it
37+
nowhere, in both versions. Any derived class (upstream's own `GraphBuilder<Impl>`
38+
included) fails to link with `undefined symbol: ~GraphBuilderInterface()`
39+
unless its user defines it. The descriptor does not supply the definition: a
40+
consumer that already writes it would then get a duplicate symbol. The test
41+
writes it, as any consumer of the contrib API must.
42+
43+
## Features
44+
45+
None. Contrib is on by default upstream and is two small TUs; there is no
46+
optional component worth a gate.
47+
48+
## Verification
49+
50+
- `mcpp test -p yaml-cpp` / `-p yaml-cpp-v080` with the pinned mcpp 2026.9.18.3,
51+
cold: `test result ok`. Objects: 32 + test TU (0.9.0), 31 + test TU (0.8.0),
52+
equal to the source count.
53+
- 0.8.0 member asserts at compile time that `yaml-cpp/fptostring.h` is absent,
54+
so it cannot pass by silently resolving 0.9.0.
55+
- openkal: both members are listed in `tests/openkal/members.toml`. Locally,
56+
`x86_64-linux-gnu`: `runs (posix)` for both. The Windows leg is taken from
57+
the PR's openkal-compat run (a local run with an unpinned mcpp failed inside
58+
openkal-llvm-runtime's libunwind for the cli11 control member as well, so it
59+
says nothing about this package).

‎.xpkgindex/plugins/mcpp.py‎

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,25 @@ def _t(en: str, zh: str, hant: str) -> Dict[str, str]:
4646
("external", _t("upstream mcpp.toml", "上游 mcpp.toml", "上游 mcpp.toml"), "neutral"),
4747
]
4848

49-
# Whether a package's test project builds and runs on openkal, measured by
50-
# tests/openkal/compat.py and recorded in .xpkgindex/openkal-compat.json. The
51-
# label is a measurement, never a declaration: a descriptor carries no field for
52-
# it. Ordered from the strongest statement to the weakest.
49+
# The two values the `openkal` facet files a package under, and the badge each
50+
# puts on the package. They are names, not sentences, and are the same in every
51+
# language:
52+
#
53+
# openkal-ecosystem a package that makes up openkal (OPENKAL_FAMILY below)
54+
# openkal-compat a package whose test project was measured to RUN in an
55+
# openkal graph, by tests/openkal/compat.py, recorded in
56+
# .xpkgindex/openkal-compat.json
57+
#
58+
# `openkal-compat` is a measurement, never a declaration: a descriptor carries
59+
# no field for it. A package measured only to build, or to fail, is filed under
60+
# neither -- the facet lists what a reader can pick, and that package's page
61+
# still shows its per-target measurement with the first diagnostic.
5362
OPENKAL_LEVELS = [
54-
("family", _t("openkal itself", "openkal 本身", "openkal 本身"), "module"),
55-
("runs", _t("runs on openkal", "在 openkal 上运行", "在 openkal 上執行"), "module"),
56-
("builds", _t("builds on openkal", "在 openkal 上构建", "在 openkal 上建置"), "header"),
57-
("fails", _t("fails on openkal", "在 openkal 上失败", "在 openkal 上失敗"), "neutral"),
58-
("n/a", _t("not applicable", "不适用", "不適用"), "neutral"),
63+
("ecosystem", _t("openkal-ecosystem", "openkal-ecosystem", "openkal-ecosystem"), "module"),
64+
("compat", _t("openkal-compat", "openkal-compat", "openkal-compat"), "module"),
5965
]
66+
# The measured level -> the facet value it is filed under.
67+
_OPENKAL_FACET = {"family": "ecosystem", "runs": "compat"}
6068
_OPENKAL_RANK = {"fails": 0, "builds": 1, "runs": 2}
6169

6270
# How a package's best-measured target relates to the platform, orthogonal to
@@ -514,11 +522,12 @@ def on_package(self, pkg, raw: Dict[str, Any]) -> None:
514522

515523
level = self._openkal_level(pkg.identity.slug)
516524
if level:
517-
pkg.facets["openkal"] = level
518525
ext["openkal"] = {"level": level,
519526
**(self.openkal_by_package.get(pkg.identity.slug) or {})}
520-
if level in ("runs", "builds", "family"):
521-
label = {k: lbl for k, lbl, _ in OPENKAL_LEVELS}[level]
527+
facet = _OPENKAL_FACET.get(level)
528+
if facet:
529+
pkg.facets["openkal"] = facet
530+
label = {k: lbl for k, lbl, _ in OPENKAL_LEVELS}[facet]
522531
pkg.extensions.setdefault("_badges", []).append(label)
523532

524533
# Wired the same way as `level` just above: a measurement, not a

‎CHANGELOG.md‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,23 @@
77

88
## [Unreleased]
99

10+
### Added
11+
12+
- **`compat.yaml-cpp` 0.8.0 与 0.9.0。** YAML 1.2 解析与生成,按上游 CMake 目标原样编译
13+
(`src/*.cpp` + `src/contrib/*.cpp`),GLOBAL + GitCode CN 镜像字节一致。上游把
14+
`YAML_CPP_STATIC_DEFINE` 作为静态构建的 PUBLIC 定义;描述符的 `defines` 到不了消费者,
15+
所以用 `yaml-cpp/dll.h` 的同名遮蔽头送达,测试在编译期断言它到了(MSVC ABI 上缺它就是
16+
dllimport 链接错误,Linux 上看不出来)。两个版本各有一个测试成员(`yaml-cpp`、
17+
`yaml-cpp-v080`),都列入 `tests/openkal/members.toml` 在 openkal 上测量。
18+
19+
### Changed
20+
21+
- **站点的 openkal 分面改为两个取值:`openkal-ecosystem` 与 `openkal-compat`。** 原先的
22+
「openkal itself / runs on openkal / fails on openkal」是句子而不是名字。构成 openkal 的
23+
包归入 `openkal-ecosystem`;测试项目在 openkal 依赖图中测得 `runs` 的包归入
24+
`openkal-compat`。只测得 `builds` 或 `fails` 的包不再归入分面,其页面仍按目标列出测量结果
25+
与第一条诊断。
26+
1027
### Fixed
1128

1229
- **索引制品按提交只定一次字节,两个托管端提供同一份。** 同一提交重跑发布(夜间 cron)

‎README.md‎

Lines changed: 40 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,14 @@
22

33
**English** | [简体中文](README.zh-CN.md)
44

5-
> The default package index repository for the [`mcpp`](https://github.com/mcpp-community/mcpp) build tool.
5+
> The default package index for the [`mcpp`](https://github.com/mcpp-community/mcpp) build tool.
66
> Browse every package online: **https://mcpplibs.github.io/mcpp-index/**
77
8-
This repository hosts the C++23 packages that `mcpp` can `add` directly — both modular libraries that are ready to
9-
`import`, and third-party C/C++ libraries built from upstream sources or headers in `compat` form. Every package maps
10-
to one `pkgs/<initial>/<name>.lua` descriptor file.
11-
12-
> **Engine floor (mcpp 2026.9.18.3):** `openkal-musl 0.15.0` and any future
13-
> `[c-abi]` package require the engine that ships with `mcpp 2026.9.18.3`
14-
> or later — the host-macro strip on Windows hosts and the freestanding
15-
> wchar realisation are what let the c-abi probe verify a declaration
16-
> without host contamination. The `min_mcpp` floor on `[indices]`,
17-
> `MCPP_VERSION`, and the per-package pins under `tests/openkal/pins.toml`
18-
> all gate this together (raising only the index floor would still let
19-
> 30 members E0006 before reading any source line). Older engines
20-
> silently misbuild `[c-abi]` packages: the build succeeds, the probe
21-
> fails, the program compiles against the wrong environment. Upgrade:
22-
> `xlings install mcpp --force`.
8+
The C++23 packages `mcpp` can `add` directly: modular libraries ready to `import`, and third-party C/C++ libraries
9+
built from upstream sources in `compat` form. Each package is one `pkgs/<initial>/<name>.lua` descriptor.
10+
11+
> **Requires mcpp 2026.9.18.3 or later** (`min_mcpp` in [`index.toml`](index.toml)). Older engines silently misbuild
12+
> `[c-abi]` packages such as `openkal-musl`. Upgrade: `xlings install mcpp --force`.
2313
2414
## Usage
2515

@@ -31,44 +21,36 @@ mcpp search <keyword> # search and refresh the index
3121
mcpp self config --mirror CN # switch to the CN mirror; GLOBAL upstream is the default
3222
```
3323

34-
For the full package list, see the **[online index site](https://mcpplibs.github.io/mcpp-index/)**.
35-
36-
## Package ecosystem and contributing
24+
## Package kinds
3725

38-
Two kinds of packages live here:
39-
40-
- **Native mcpp module libraries**: shipped as C++23 modules and ready to `import` — `mcpplibs.*`, `nlohmann.json`,
41-
`imgui`, `ffmpeg`, `opencv`, plus libraries developed on top of mcpp by users and registered into the index (such as
42-
`tensorvia-cpu` and `huxerui.huxerui`). Their upstream usually carries its own `mcpp.toml`, so the descriptor (Form A) only declares
43-
metadata and a download address.
44-
- **Third-party C/C++ libraries (`compat`)**: upstream offers no mcpp support, so the descriptor (Form B) inlines the
45-
build information. These come in several shapes — header-only, plain C sources, C++23 module wrapper — with optional
46-
components gated behind `features` and a GitCode CN mirror configured.
26+
- **Native mcpp module libraries** (Form A): upstream carries its own `mcpp.toml`; the descriptor only declares
27+
metadata and a download address. `mcpplibs.*`, `nlohmann.json`, `imgui`, `opencv`, `tensorvia-cpu`, …
28+
- **Third-party C/C++ libraries** (`compat`, Form B): upstream has no mcpp support, so the descriptor inlines the build.
29+
Header-only, C/C++ sources, or a C++23 module wrapper; optional parts sit behind `features`; a GitCode CN mirror
30+
serves the same bytes.
4731

4832
### Reference examples
4933

50-
A few descriptors worth opening first, one per common shape:
51-
52-
| Shape | Example | What it shows |
53-
|------|------|------|
54-
| Native module library (Form A) | [`mcpplibs.cmp`](pkgs/c/cmp.lua) · [`mcpplibs.tinyhttps`](pkgs/t/tinyhttps.lua) · [`gzj-creator.galay`](pkgs/g/gzj-creator.galay.lua) | Upstream carries its own `mcpp.toml`; CMP demonstrates a coroutine runtime, while Galay demonstrates a multi-module package with feature-scoped protocol layers |
55-
| C-source compat | [`compat.cjson`](pkgs/c/compat.cjson.lua) | One `.c` compiled into a lib; the optional extension sits behind a `features` gate |
56-
| Header-only | [`compat.gtl`](pkgs/c/compat.gtl.lua) | Nothing to compile — `include_dirs` and an anchor TU |
57-
| Whole-source build + generated config | [`compat.c-ares`](pkgs/c/compat.c-ares.lua) | The config header configure would have produced is snapshotted into `generated_files` |
58-
| Multi-component upstream flattened into one lib | [`compat.recastnavigation`](pkgs/c/compat.recastnavigation.lua) | Recast Navigation 1.6.0 — upstream is five inter-dependent CMake libraries; here the two every consumer uses are the base and the other three are `features`, all compiled into one lib. Their dependency edges have to be rebuilt by hand, which is why `debug-utils` carries `implies = { "tilecache" }`: upstream links DetourTileCache unconditionally, and without the implication a consumer asking only for debug drawing fails at link with missing `dtTileCache*` symbols. Upstream's install puts every header flat under `include/recastnavigation/` **and** keeps both that directory and its parent on the interface include path, so both `<Recast.h>` and `<recastnavigation/Recast.h>` are legal against a real install — 26 generated forwarding headers restore the second spelling for a source-tree build. `RECASTNAVIGATION_DT_POLYREF64` and `RECASTNAVIGATION_DT_VIRTUAL_QUERYFILTER` are deliberately NOT features: they change the ABI of types crossing the library boundary, and a feature's `defines` reach only the package's own TUs |
59-
| C++23 module wrapper | [`nlohmann.json`](pkgs/n/nlohmann.json.lua) | A generated `.cppm` turns a header-only library into `import` |
60-
| C++23 module, upstream's own | [`khronos.vulkan-hpp`](pkgs/k/khronos.vulkan-hpp.lua) | Khronos ships `vulkan.cppm`, so the descriptor just names it — `import vulkan;` with nothing authored here |
61-
| External build system | [`compat.openssl`](pkgs/c/compat.openssl.lua) | An `install()` hook drives upstream's own Perl Configure + Make |
62-
| Form A whose consumer deps must be written by hand | [`huxerui.huxerui`](pkgs/h/huxerui.huxerui.lua) | HuxerUI declares its GTK4 stack on the TARGET axis, which is the form mcpp recommends and which a descriptor structurally cannot carry — three platform blocks, and a cfg selector is not a platform. `mcpp emit xpkg` says so and emits empty `deps`, so the 36-entry closure is transcribed into `xpm.linux.deps` at PLATFORM level (a per-version `deps` is inert). Its `licenses`/`repo` also deliberately disagree with what emit produces |
34+
One descriptor per common shape:
6335

64-
The full catalog — every shape this index has needed, and the reasoning behind each descriptor including what it
65-
deliberately leaves out — is in **[Descriptor examples by shape](docs/descriptor-examples.md)**.
36+
| Shape | Example |
37+
|------|------|
38+
| Native module library (Form A) | [`mcpplibs.tinyhttps`](pkgs/t/tinyhttps.lua) · [`gzj-creator.galay`](pkgs/g/gzj-creator.galay.lua) |
39+
| C sources + `features` | [`compat.cjson`](pkgs/c/compat.cjson.lua) |
40+
| C++ sources, several versions | [`compat.yaml-cpp`](pkgs/c/compat.yaml-cpp.lua) |
41+
| Header-only | [`compat.gtl`](pkgs/c/compat.gtl.lua) |
42+
| Generated config header | [`compat.c-ares`](pkgs/c/compat.c-ares.lua) |
43+
| C++23 module wrapper | [`nlohmann.json`](pkgs/n/nlohmann.json.lua) |
44+
| C++23 module shipped by upstream | [`khronos.vulkan-hpp`](pkgs/k/khronos.vulkan-hpp.lua) |
45+
| External build system (`install()`) | [`compat.openssl`](pkgs/c/compat.openssl.lua) |
46+
47+
Every other shape, and why each descriptor is written the way it is, is in
48+
**[Descriptor examples by shape](docs/descriptor-examples.md)**.
6649

6750
### Adding a package
6851

69-
The full procedure is defined in the agent skill
70-
[`add-mcpp-index-package`](.agents/skills/add-mcpp-index-package/SKILL.md). Hand the instruction below to an agent
71-
(Claude Code, for example) and it will invoke that skill to write the descriptor and carry out the whole flow:
52+
The procedure is the agent skill [`add-mcpp-index-package`](.agents/skills/add-mcpp-index-package/SKILL.md). Hand an
53+
agent (Claude Code, for example) this instruction:
7254

7355
```text
7456
Following this repo's skill `.agents/skills/add-mcpp-index-package`, add <library name / repo URL> @<version> to
@@ -78,27 +60,18 @@ member; verify locally with the same mcpp version CI pins by running `mcpp test
7860
the online index; open a PR and confirm CI is green.
7961
```
8062

81-
Detailed documentation lives in [`docs/`](docs/), written for humans and agents alike:
82-
83-
- [Library shapes and descriptor templates](docs/package-types.md): descriptor templates and samples for each shape,
84-
plus how to write the minimal project.
85-
- [Descriptor examples by shape](docs/descriptor-examples.md): the full catalog of what is already in the index, and
86-
why each descriptor is written the way it is.
87-
- [The CN mirror loop](docs/cn-mirror.md): `gtc` and gitcode operations, plus the fallback when you have no
88-
`mcpp-res` access.
89-
- [openkal compatibility](docs/openkal-compat.md): what the `openkal` label on the site means, how it is measured, and
90-
how a package is adapted to an openkal graph.
91-
- [Repository layout, schema and CI](docs/repository-and-schema.md): field cheat-sheet, selective-run mechanics and
92-
local lint.
93-
- The **authoritative** judge of a field is `mcpp xpkg parse` (exactly what CI runs: an unknown mcpp-segment field
94-
fails outright instead of being silently ignored); for semantics and constraints see
95-
[`docs/spec/`](https://github.com/mcpp-community/mcpp/tree/main/docs/spec) in the mcpp repository.
96-
97-
> Once a PR is open, `validate` runs lint automatically and selects the workspace members affected by the changed
98-
> library (the whole test surface is one mcpp workspace, and the public module packages
99-
> `imgui`/`ffmpeg`/`opencv`/`tinyhttps` are ordinary members too — the `compat` redirect is declared at the workspace
100-
> root and inherited by members, while members that consume another namespace override it themselves, with zero shell
101-
> driving). After the merge, `deploy-site` publishes it to the online browser.
63+
A PR runs lint and tests only the workspace members that depend on the changed descriptors; after the merge,
64+
`deploy-site` publishes the site.
65+
66+
## Documentation
67+
68+
- [Library shapes and descriptor templates](docs/package-types.md)
69+
- [Descriptor examples by shape](docs/descriptor-examples.md)
70+
- [The CN mirror loop](docs/cn-mirror.md)
71+
- [openkal compatibility](docs/openkal-compat.md): the `openkal-ecosystem` / `openkal-compat` labels on the site
72+
- [Repository layout, schema and CI](docs/repository-and-schema.md)
73+
- The authoritative check of a field is `mcpp xpkg parse`, which CI runs; semantics are in mcpp's
74+
[`docs/spec/`](https://github.com/mcpp-community/mcpp/tree/main/docs/spec).
10275

10376
## Related links
10477

0 commit comments

Comments
 (0)