Skip to content

compat.zlib 应当声明 soname = "libz.so.1" —— 这是「两个提供者合成一个」的唯一途径(等 mcpp 下限) #270

Description

@Sunrisepeak

承接 mcpp-community/mcpp#519不要现在合入 —— 见文末的发布顺序。

问题

任何同时用到 compat.zlib(直接,或经 libpng / eui-neo)和某个加载
libz.so.1 的预构建库的工程,进程里会有两份 zlib,而可执行文件里那份
在两者共有的每个符号上获胜。实测(mcpp 2026.8.28.2,生态自己的 glib):

$ mcpp build
warning: trayapp: 88 symbols in this image are also provided by a library it loads.
    adler32()  compress()  … and 82 more
  Also provided by:
    …/xim-x-zlib/1.3.1/lib/libz.so.1.3.1
$ LD_DEBUG=bindings ./trayapp
binding file …/libgio-2.0.so.0 to ./trayapp: normal symbol `inflate'
binding file …/libgio-2.0.so.0 to ./trayapp: normal symbol `inflateGetHeader' [ZLIB_1.2.2]

最后一行值得单看:带版本的引用绑到了无版本的定义,而加载器接受了。
同一情形跨 .so 时在链接期是硬错误。

为什么 linkage = "shared" 单独不够

compat.zlib 换成共享形态确实让 exe 的 88 个导出归零、诊断静默 ——
但 mcpp 产出的文件叫 libzlib.so没有 SONAME,而 libgio 找的是
libz.so.1。实测结果:进程里从一份变两份,并且没有任何诊断
(两边都是 .so,检查只看可执行文件)。

⭐ 也就是说:形态轴单独用会把一个可检测的缺陷换成一个不可检测的

改动

targets = { ["zlib"] = { kind = "lib", soname = "libz.so.1" } },

一行。之后消费者写 "compat.zlib" = { linkage = "shared" },mcpp 产出带
SONAME libz.so.1 的库并生成同名别名,libgio 与工程解析到同一个文件

⚠️⚠️ 发布顺序:现在合会让旧客户端全部读不了这个包

在 mcpp 2026.8.28.2 之前,soname 写在非 shared 目标上不是被忽略,而是
整份 manifest 加载失败(types.cppmvalidate_target_soname 返回错误,
两个解析器都把它变成 std::unexpected)。

⇒ 前置判据不是「2026.8.28.2 发布了」,而是索引 latest 的 mcpp 下限跨过它
provides 硬失败那次同型。

⚠️ 还要先确认:$ORIGIN 与依赖包 runtime_search_dirs
link_line::UnitTail 里的相对次序,决定了「正确的 soname 是否真的赢」。
这一步是待测,不是推理 —— 与 mcpp-community/mcpp#304 合流。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions