Skip to content

feat: 包身份规范化 —— 上游库归上游命名空间,版本对齐上游 - #165

Merged
Sunrisepeak merged 2 commits into
mainfrom
feat/upstream-identity
Aug 6, 2026
Merged

feat: 包身份规范化 —— 上游库归上游命名空间,版本对齐上游#165
Sunrisepeak merged 2 commits into
mainfrom
feat/upstream-identity

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

落地 #163。判据两条:命名空间说的是这个库是谁的,不是谁打的包;版本说的是你拿到的是哪一版上游。

迁移前 迁移后 上游
mcpplibs:imgui@0.0.6 ocornut:imgui@1.92.8 ocornut/imgui
mcpplibs:ffmpeg@0.0.3 ffmpeg:ffmpeg@8.1.2 FFmpeg
mcpplibs:opencv@0.0.10 opencv:opencv@5.0.0 opencv/opencv
mcpplibs:llamacpp@0.1.0 ggml-org:llamacpp@b10069 ggml-org/llama.cpp
mcpplibs:grpc@1.83.0 grpc:grpc@1.83.0 grpc/grpc

-m 仓库的对应 PR 均已合入并发布 tag:imgui-m#12ffmpeg-m#7opencv-m#19llama.cpp-m#2grpc-m#2

新增两个包(gRPC codegen 链路)

  • grpc:grpc-plugin —— grpc_cpp_plugin,上游 src/compiler/*,作为 host tool 构建。独立包不是风格选择:mcpp 把一个包编成一个对象池并把每个实现对象链进它的每个 kind="bin" 目标(plan.cppm 无 per-target 源码分区),所以插件若住在 grpc 里会链进约 1000 个 gRPC TU 并继承 OpenSSL/re2/c-ares。
  • mcpplibs:grpcgen —— 本生态自己写的 163 行构建规则,故留在 mcpplibs。

两者 manifest 在归档子目录里,默认查找够不到两级,用显式 mcpp = "*/plugin/mcpp.toml" 指针。

旧条目冻结而非删除

已在用它们的消费者继续解析得到,新版本只在新条目下发布。grpc 是例外:它 2026-08-05 才进索引(#151),满打满算一天,唯一消费者是本仓成员,为一天的历史留永久重复条目不划算,故就地迁移。

MCPP_VERSION → 2026.8.6.1 是前置,不是顺手升级

本次对齐把 module 层与 compat 的版本变成相同,于是踩到 mcpp 的一个既有 bug:install_path 的 legacy 扫描匹配任何 -x-<shortName> 结尾的目录、不看命名空间,查 ocornut:imgui@1.92.8 会拿到 compat-x-imgui/1.92.8。它一直够不到,正是因为两侧版本从不相同。已由 mcpp#364 修复并发布。

index.tomlmin_mcpp 不动。 会撞的两个 compat 邻居都是 Form B,旧客户端撞上时是响亮报错而不是静默用错包;下限是让整个索引对所有旧客户端失效的闸门(#349),只该在描述符真的读不动时抬。这里读得动,差的是解析得对 —— 用 CI pin 表达就够。

成员

五个成员的 [indices] 键与依赖段跟着迁。索引表按命名空间取键,包搬走了而键没搬,被测的就不再是这个 checkout(静默回落到线上索引)。

已知缺口(诚实记下)

grpc-plugingrpcgen 没有成员覆盖。它们需要 grpcmcpplibs 两个命名空间同时从 checkout 解析,而"每个成员至多一个项目索引"是硬约束(#238)。描述符发布之后再补 codegen 成员;在此之前该链路由 grpc-m 自己的 CI 覆盖 —— examples/greeter 经 grpcgen 生成 stub 并跑通真实 RPC,linux 1h46m、macOS 43m 均已绿。

本地验证

  • 全量 lint(lua 语法 / spec-name-xpm / 前导 v / mirror urls / 身份形态)ALL PASS
  • 11 个受影响描述符逐个 mcpp xpkg parse(strict)OK
  • CN 镜像四个逐个 curl -fsSL 实测 200,字节数与 tarball 一致
  • ocornut:imgui@1.92.8 在 2026.8.6.1 上实测安装并构建成功(同环境 A/B:旧版失败)

判据两条:**命名空间说的是这个库是谁的,不是谁打的包;版本说的是你拿到的是哪一版
上游。** 规则与全量迁移表见 #163。

    mcpplibs:imgui@0.0.6     → ocornut:imgui@1.92.8
    mcpplibs:ffmpeg@0.0.3    → ffmpeg:ffmpeg@8.1.2
    mcpplibs:opencv@0.0.10   → opencv:opencv@5.0.0
    mcpplibs:llamacpp@0.1.0  → ggml-org:llamacpp@b10069
    mcpplibs:grpc@1.83.0     → grpc:grpc@1.83.0

新增两个包(gRPC codegen 链路):`grpc:grpc-plugin`(上游 src/compiler/*,作为 host
tool)与 `mcpplibs:grpcgen`(本生态自己写的构建规则,故留在 mcpplibs)。两者的
manifest 在归档子目录里,默认查找够不到两级,用显式 `mcpp = "*/…/mcpp.toml"` 指针。

**旧条目冻结保留而非删除** —— 已在用它们的消费者继续解析得到,新版本只在新条目下
发布。grpc 是例外:它 2026-08-05 才进索引(#151),满打满算一天,唯一消费者是本仓成
员,为一天的历史留永久重复条目不划算,故就地迁移。

`mcpplibs` 只剩名副其实的那些(cmdline / tinyhttps / llmapi 等)。

## MCPP_VERSION 抬到 2026.8.6.1 是前置,不是顺手升级

本次对齐把 module 层与 compat 的版本变成相同,于是踩到了 mcpp 的一个既有 bug:
`install_path` 的 legacy 扫描匹配任何 `-x-<shortName>` 结尾的目录、不看命名空间,查
`ocornut:imgui@1.92.8` 会拿到 `compat-x-imgui/1.92.8`。mcpp#364 修掉了它。

`index.toml` 的 min_mcpp **不动**:会撞的两个 compat 邻居都是 Form B,旧客户端撞上
时是响亮报错而不是静默用错包;下限是让整个索引对旧客户端失效的闸门(#349),只该在
描述符真的读不动时抬。

## 成员

五个成员的 `[indices]` 键与依赖段跟着迁 —— 索引表按命名空间取键,包搬走了而键没搬,
被测的就不再是这个 checkout(静默回落到线上索引)。

## 已知缺口

`grpc-plugin` 与 `grpcgen` 没有成员覆盖。它们需要 `grpc` 与 `mcpplibs` 两个命名空间
同时从 checkout 解析,而"每个成员至多一个项目索引"是硬约束(#238)。描述符发布之后
再补一个 codegen 成员;在此之前该链路由 grpc-m 自己的 CI 覆盖(examples/greeter 经
grpcgen 生成 stub 并跑通真实 RPC)。
CI 抓到三个分片红在 `opencv.opencv@0.0.10` / `@0.0.9` —— 命名空间迁了、版本没迁。
原因是我的替换只写了裸字符串形式 `opencv = "0.0.10"`,而这两个成员用的是表形式
`opencv = { version = "0.0.10", features = ["dnn"] }`。**为一种语法形式写替换,却假
设它覆盖了全部。**

于是不再逐个猜,改用全量扫描找残留 —— 结果比 CI 报的更多:`llamacpp-metal` 根本
不在我上一轮的成员清单里,`[indices]` 键、依赖段、版本三处都没迁。

修复过程中我自己又引入一个:那条 `version = "0.1.0"` 的无差别替换把成员**自身**的包
版本也改成了 b10069。是靠"每个成员的 [indices] 键必须与其依赖段命名空间一致"这条普
查发现的,不是靠信任修复。已还原为 0.1.0。

复核:
* 残留扫描清零
* 全成员 indices 键与依赖命名空间逐一对齐
* 三个被改文件的包自身版本均为 0.1.0
* lint(语法 / 身份形态 / mirror urls)PASS
* 七个迁移描述符的版本键覆盖三平台;grpc 是 2 平台,这是它 compat.openssl 无
  windows 条目的既有例外,不是遗漏
@Sunrisepeak
Sunrisepeak force-pushed the feat/upstream-identity branch from 45c0fe5 to de8801b Compare August 6, 2026 04:34
@Sunrisepeak

Copy link
Copy Markdown
Member Author

CI 结论

九条检查里八条绿,唯一的红是 workspace (linux 2/3) 里的 openssl,同分片其余 20 个成员测试全过。

openssl 在 main 上同样红(run 31048019080),先于本 PR 存在。根因已定位并有直接证据:

$ <xim-x-gcc/16.1.0>/bin/g++ -print-sysroot
/home/speak/workspace/github/openxlings/xim-pkgindex-fromsource/.xlings/subos/default

gcc payload 报出的是构建它那台机器上的路径(两份独立安装报同一个值:一份是全新沙箱里现装的、一份是本机日常环境的)。CI 上该路径不存在 → sysroot 落空 → assert.h: No such file。修复在 xim-pkgindex#463,证据已贴过去。

上一轮 CI 抓到的两处我的疏漏(已修)

  1. 表形式的依赖版本没跟着迁 —— 我的替换只写了裸字符串形式 opencv = "0.0.10",而 opencv-module-dnn / -unifont 用的是 opencv = { version = "0.0.10", features = [...] }
  2. llamacpp-metal 整个漏掉 —— 它不在我的成员清单里,[indices] 键、依赖段、版本三处都没迁。CI 没报是因为它只在 macOS 腿跑,而那条腿先死在 opencv 上了。

改法不是再猜一次,而是全量扫描 + "每个成员的 [indices] 键必须与其依赖段命名空间一致"的普查 —— 后者还抓出我修复时自己引入的一处(无差别替换把成员自身的包版本也改了)。

沙箱实证(已发布产物,非本 checkout)

   Compiling grpc.grpc v1.83.0
   Compiling grpc.grpc-plugin v1.83.0
   Compiling mcpplibs.grpcgen v1.83.0
     Running target/.../codegen-probe
ok: generated stub constructed against the linked gRPC runtime

ocornut:imgui@1.92.8 默认档可用;app feature 双向验证(不声明则 module 'imgui.app' imported but not provided 并失败)。

@Sunrisepeak
Sunrisepeak merged commit 45f45f9 into main Aug 6, 2026
9 of 10 checks passed
@Sunrisepeak
Sunrisepeak deleted the feat/upstream-identity branch August 6, 2026 05:51
Sunrisepeak added a commit that referenced this pull request Aug 8, 2026
两个包在装了同名系统开发包的机器上会拿错头,而 CI 和本地一直看不见:默认
工具链 gcc 是通过 --sysroot 进 xlings subos 编译的,那里 /usr/include 干干
净净。换到 llvm(无 sysroot)宿主机的头就进了默认搜索路径,两个都当场炸。

## compat.ffmpeg:-idirafter 排在系统目录之后

源码根走 include_dirs_after 是 #249 为 macOS 修的 —— 大小写不敏感的文件系统
上 ffmpeg 的 VERSION 会遮蔽 libc++ 的 <version>。但 -idirafter 的语义是排在
**系统目录之后**,于是在装了 libavutil-dev 的 Debian/Ubuntu 上
(/usr/include/x86_64-linux-gnu 是默认搜索目录),vendored 8.1.2 的每一个
`#include "libavutil/..."` 都输给宿主机的 6.1.1。

不是优雅降级:全局 -DHAVE_AV_CONFIG_H 让宿主机的**公开**头去 include dev 包
根本不装的私有头('x86/bswap.h'、libavutil/internal.h),再叠加 6.x/8.x 的
类型错配(enum AVAlphaMode 不完整、SwsContext 少 typedef)。

改成按 OS 放置,且**只能二选一**:同一个目录同时出现在 -I 和 -idirafter 会
被编译器去重到最后那个位置,保留一份冗余的 -idirafter 就会静默抵消 -I。
clang 22.1.8 上实测过:同一条命令行,只删掉重复的 -idirafter 就编过。

  linux   → include_dirs。文件系统大小写敏感,VERSION 遮蔽不了 <version>;
            而它是唯一有系统 ffmpeg 可输的平台。
  macosx  → include_dirs_after,#249 原样。
  windows → include_dirs_after。NTFS 同样大小写不敏感,换 -I 会把 #249 带
            回来,而那边的系统目录里没有 libav*。

生成器 tools/compat-ffmpeg/gen_multiplatform.py 同步改。per-OS 快照已不在,
描述符是手改的,两边保持一致。

## compat.catch2:上游 2.13.10 漏 #include <new>

单头调了两次 new(std::nothrow)(catch.hpp:977 / :14594)却从不包含 <new>。
libstdc++ 会从别的头把它带进来,libc++ 不会,于是每个 clang 消费者都挂在
"no member named 'nothrow' in namespace 'std'"。Catch2 v2 上游已 EOL。

修法是在 mcpp_generated 里放 shim:#include <new> 后 #include_next 到上游那
份,而不是 patch 一份 17k 行的头 —— sha256 钉住的 tarball 仍是唯一事实来源。
这要求 mcpp_generated 排到 include_dirs 最前,因为 #include_next 从本文件所在
目录之后继续搜。

不能用 cflags 解:描述符的 cflags 到不了消费者的 TU(实测消费端只拿到
include_dirs 和 -std),而 catch.hpp 恰恰是消费者包含的。

## 删除冻结的 mcpplibs:opencv@0.0.10

#165 已把它迁到 opencv:opencv@5.0.0 并冻结保留。索引内三个消费成员早就写成
限定形式,删除零 fallout;顺带修掉三处说自己在消费裸名的过时注释。

注意 `mcpp new -t opencv:imgproc` 会随之失效 —— `-t` 的 spec 语法里冒号是
模板分隔符,表达不出 ns:name,所以在 mcpp 给限定名留出位置之前,模板路径
拿不到 opencv。

## 验证

在一台装了 ffmpeg 6.1.1 dev 头和 Catch2 v3 的机器上,llvm@22.1.8 与
gcc@16.1.0 双工具链:

  ffmpeg 消费者   llvm 2311 个 .o(libswscale 71,原先整批全灭);二进制断言
                  avutil_version()>>16 == 60 通过 —— 用的确是 vendored 8.1.2
  gcc 回归        2281 个 .o,同样通过,走新的 -I<root> + sysroot
  opencv 端到端   import opencv.cv; + cvtColor/GaussianBlur,llvm 下通过
  catch2          catch2 / catch2-main / catch2-v2 三成员双工具链通过

已知未修:catch2-v2-main 在 llvm 下仍失败。catch2_main.cpp 用
__has_include(<catch2/catch_all.hpp>) 判 v2/v3,该探测同样会落到系统目录,
在装了系统 Catch2 v3 的机器上把 v2 判成 v3,链接报 undefined Catch::Session。
同一类问题,但要不问文件系统就知道版本,得等 per-version build blocks
(mcpp#290)。回退本提交后同样失败,是既有问题而非本次引入。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant