承接 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.cppm 的 validate_target_soname 返回错误,
两个解析器都把它变成 std::unexpected)。
⇒ 前置判据不是「2026.8.28.2 发布了」,而是索引 latest 的 mcpp 下限跨过它。
与 provides 硬失败那次同型。
⚠️ 还要先确认:$ORIGIN 与依赖包 runtime_search_dirs 在
link_line::UnitTail 里的相对次序,决定了「正确的 soname 是否真的赢」。
这一步是待测,不是推理 —— 与 mcpp-community/mcpp#304 合流。
承接
mcpp-community/mcpp#519。不要现在合入 —— 见文末的发布顺序。问题
任何同时用到
compat.zlib(直接,或经 libpng / eui-neo)和某个加载libz.so.1的预构建库的工程,进程里会有两份 zlib,而可执行文件里那份在两者共有的每个符号上获胜。实测(mcpp 2026.8.28.2,生态自己的 glib):
最后一行值得单看:带版本的引用绑到了无版本的定义,而加载器接受了。
同一情形跨
.so时在链接期是硬错误。为什么
linkage = "shared"单独不够把
compat.zlib换成共享形态确实让 exe 的 88 个导出归零、诊断静默 ——但 mcpp 产出的文件叫
libzlib.so且没有 SONAME,而 libgio 找的是libz.so.1。实测结果:进程里从一份变两份,并且没有任何诊断(两边都是
.so,检查只看可执行文件)。⭐ 也就是说:形态轴单独用会把一个可检测的缺陷换成一个不可检测的。
改动
一行。之后消费者写
"compat.zlib" = { linkage = "shared" },mcpp 产出带SONAME
libz.so.1的库并生成同名别名,libgio 与工程解析到同一个文件。在 mcpp 2026.8.28.2 之前,
soname写在非 shared 目标上不是被忽略,而是整份 manifest 加载失败(
types.cppm的validate_target_soname返回错误,两个解析器都把它变成
std::unexpected)。⇒ 前置判据不是「2026.8.28.2 发布了」,而是索引
latest的 mcpp 下限跨过它。与
provides硬失败那次同型。$ORIGIN与依赖包runtime_search_dirs在link_line::UnitTail里的相对次序,决定了「正确的 soname 是否真的赢」。这一步是待测,不是推理 —— 与
mcpp-community/mcpp#304合流。