Skip to content

图形栈:可独立分发的库改走源码构建,版本号对齐上游 - #289

Merged
Sunrisepeak merged 5 commits into
mainfrom
fix/graphics-stack-source-builds
Aug 30, 2026
Merged

图形栈:可独立分发的库改走源码构建,版本号对齐上游#289
Sunrisepeak merged 5 commits into
mainfrom
fix/graphics-stack-source-builds

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

把图形栈里可独立分发的库改成源码构建,并把版本号对齐到上游真实发布号。

判据修正:可否独立分发,仅此而已

之前 compat.libdrm / compat.wayland 做成绑定的理由是「生态 payload 里已经有一份同名库,再建一份会冲突」。这个理由是错的,已实测推翻:

libdrm.so.2 解析到
单独看 Mesa 的 libgbm.so.1 xim-x-libdrm/2.4.123/lib/(它自己的绝对 RUNPATH)
真实消费者进程里 <consumer>/target/.../bin/libdrm.so.2(消费者链接的那份)

进程内 libdrm.so.2 只有 1 份,而且 Mesa 的 GBM 用它真的分配出了 buffer(gbm_bo_create ok stride=256)。

原因:DT_NEEDED 的 soname 一旦进入 link map 就被复用,ld.so 不再搜索,自然不会去看 payload 的 RUNPATH。消费者直接链接的库先被映射,其余跟着它走。

前提是 kind = "shared" 且 soname 正确。用本索引默认的 kind = "lib"(对象并进消费者)就没有 .so 可复用:payload 那份照常为 Mesa 加载,消费者另有一份合并进来的,libdrm 的 file-static 状态(drmHashTable/nr_fds/connection,都是 .bss 里的 OBJECT)在同一批 fd 上分成两套账。这正是 soname 防的事。

三个测试成员都用 dladdr 断言加载的确实是本包所建,不是 payload 那份 —— 否则源码构建就是摆设。

变更

新增(源码构建)

  • compat.libffi 3.4.8 —— x86 汇编自带架构门控(ffi.c__i386__ffiw64.c/unix64.S/win64.S__x86_64__),所以全部列进 sources 由预处理器筛,不需要 per-arch 源列表。fficonfig.h 是 configure 的探测结果、无法从 tarball 推导,内联;ffi.h 推导,于是 install() 照 configure 的四个替换从 ffi.h.in 生成 —— 版本一动就跟着动,不会悄悄发旧头。测试真的跑 ffi_call,整数与 SSE 两条路径都走(只测整数会漏掉 unix64.S 一半的代码)。
  • compat.expat 2.7.1 —— 三个 TU,不是五个:xmltok_impl.c / xmltok_ns.c 是被 xmltok.c include 五次的(每次带不同的宏),列进 sources 会产生重复符号。测试解析真实文档,覆盖 XML_NS 前缀展开与 DTD 实体 —— 这两个是 expat_config.h 里的功能开关而非探测项,配错了库照样链得上、只是行为变了。

改为源码构建

  • compat.libdrm 2026.08.302.4.134 —— 5 个 TU + 内联的 generated_static_table_fourcc.h(65 行,gen_table_fourcc.py 的产物,不在发布 tarball 里),零依赖(host 0 / ecosystem 0 / index 0)。两个 include 根仍是最会咬人的地方:公开头在源码根、uapi 头在 include/drm/,而 xf86drm.h 第 40 行是裸的 #include <drm.h>

版本对齐

  • compat.libgbm 2026.08.2925.0.7(Mesa 上游版本),并把 xim:mesa 钉到 25.0.7.2 —— 不钉的话这个版本号承诺不成立。形态保持绑定:GBM 是 Mesa 内部 build target(src/gbm/meson.buildlink_with: [libloader],而 libloaderidep_mesautil 约 120 个 TU),且它是个 loader,后端就是 Mesa 自己的 dri_gbm.so
  • compat.egl 2026.08.301.7.0(libglvnd 上游版本),同样钉住 payload。仍是绑定,但理由是工作量不是判据:libglvnd 是可独立分发的项目,只是 libEGL.so 还要 egl_dispatch_stubs(Python 生成)、winsys_dispatch 和完整的 libGLdispatch.so,加 vendor 发现路径 —— 描述符里写明了。

为什么版本号不再是日期戳

索引里日期戳只该留给「上游根本没有版本」的情况(khrplatformopengl 是 Khronos 无版本注册表头)。这四个包都有真实上游版本,之前用日期是错的。

libffi 取 3.4.8 而非生态的 3.4.4、expat 取 2.7.1 而非 2.6.2、libdrm 取 2.4.134 而非 2.4.123 —— 都是当前上游发布号,同时绕开了 mcpp-community/mcpp#533:store 的已安装查找按 (name, version) 匹配且忽略 namespace,撞上就静默跳过 install(),报错还会伪装成 /bin/sh: -shared: not found。比 payload 新是安全的,soname 就是干这个的。

验证

六个测试成员本地全绿(libdrm / libffi / expat / libgbm / egl / wayland),check_cross_package_refscheck_platform_version_paritycheck_duplicate_versions、Lua 语法、mcpp xpkg parse 均通过。CN 镜像六个资源已上传并回取逐字节比对一致

后续

wayland 的源码化拆到下一个 PR:它需要 build.mcpp(wayland-scanner 得先编译出来才能生成两个库大部分体量的约 13000 行),所以走 Form A fork —— mcpplibs/wayland 已建好并发布 1.26.0,四个 workspace 成员(scanner / client / server / util,含 import wayland.client; 模块层),CI 跑 gcc+llvm。之所以分开,是因为它依赖本 PR 的 compat.libffi,而 [indices] 重定向按 namespace 取键、一个仓只能挂一个键(同路径挂两个键会报歧义),所以在本 PR 的 CI 里 freedesktop.*compat.* 没法同时从本地 checkout 解析。

The two checks that require GBM_BACKENDS_PATH were red on this PR's CI, and
they had never actually run before: the workspace leg of #281 was CANCELLED, so
the member merged without them ever executing.

The variable is not this package's to set. It comes from xim-pkgindex's
graphics discovery layer (openxlings/xim-pkgindex#713, merged today) and reaches
the process through mcpp's subos-env handling, so whether it is present is
decided by the ECOSYSTEM VERSION. mcpp-index's CI runs a pinned mcpp
(MCPP_VERSION = 2026.8.27.2) whose vendored xlings predates that row — a hard
assertion there is red everywhere the ecosystem is older and green everywhere it
is current, which says nothing about the package.

So the presence check is reported rather than asserted, and the checks that DO
run when it is set are the real ones — the directory must exist AND hold a
backend libgbm can dlopen, which is stronger than presence alone. A regression
in either the DISCOVERY row or mcpp's env injection still lands here on any
ecosystem that has the feature; on an older one the member says which
requirement is missing and tests the package itself.

Verified locally, where the ecosystem does declare it: both binaries green with
the full backend-path checks running.
@Sunrisepeak
Sunrisepeak merged commit 11555ab into main Aug 30, 2026
11 checks passed
Sunrisepeak pushed a commit to mcpp-community/mcpp that referenced this pull request Aug 30, 2026
mcpplibs/mcpp-index#289 replaced the date-stamped versions with the upstream
projects' own release numbers, and made compat.libdrm a source build. The
example follows:

    libdrm  2026.08.30 -> 2.4.134   (now built from source)
    libgbm  2026.08.29 -> 25.0.7    (Mesa's version)
    egl     2026.08.30 -> 1.7.0     (libglvnd's version)

The README's 'The packages' section said none of them vendors a source tree,
which is no longer true, and the closure listing is re-measured against the
published index. The interesting line is the first one: libdrm.so.2 resolves to
the project's OWN build output rather than the payload copy Mesa was linked
against — a soname already in the link map is reused, so the consumer's copy
wins and Mesa's GBM allocates through it. That is why a library the payload
also carries can still be built from source.
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.

2 participants