为何 libncursesw.so.6 依赖 libtinfo.so.6, 而非对应的 libtinfow.so.6 ?

系统安装、升级讨论
版面规则
我们都知道新人的确很菜,也喜欢抱怨,并且带有浓厚的Windows习惯,但既然在这里询问,我们就应该有责任帮助他们解决问题,而不是直接泼冷水、简单的否定或发表对解决问题没有任何帮助的帖子。乐于分享,以人为本,这正是Ubuntu的精神所在。
回复
offline
帖子: 42
注册时间: 2012-02-06 11:26

为何 libncursesw.so.6 依赖 libtinfo.so.6, 而非对应的 libtinfow.so.6 ?

#1

帖子 offline » 2023-04-22 6:54

  Debain 提供的 ncurses 库有“非宽版”和“宽版”两种,后者带有 w 后缀,能够处理 CJK 双宽度字符。但为何有 libncursesw.so.6, 却没有 libtinfow.so.6 ? 宽版 ncurses 依赖的也是“非宽版”的 libtinfo, 而自己编译的宽版的 ncurses, 结果却是 libtinfow. 由于 Debian 是基础发行版,这一行为导致 Ubuntu 等许多其他发行版也跟着这样。用 libtinfow.so.6 去搜索,却依然能搜索到一些信息,说明也有某些发行版存在 libtinfow.so.6.

  Debain 对 ncurses 做的这种改动应该会导致 ABI 不兼容吧?如果要以二进制文件的形式分发基于 ncurses 的软件,该怎么办? Debain 为何要修改它的 ABI 呢?
头像
astolia
论坛版主
帖子: 6540
注册时间: 2008-09-18 13:11

Re: 为何 libncursesw.so.6 依赖 libtinfo.so.6, 而非对应的 libtinfow.so.6 ?

#2

帖子 astolia » 2023-04-24 11:40

因为libtinfo6包里面的libtinfo.so.6就是带--enable-widec编译出来的,也就是你说的libtinfow.so.6

至于ABI,建议你在下“不兼容”的结论前,先去看看它的符号表,查一下对应函数的定义
offline
帖子: 42
注册时间: 2012-02-06 11:26

Re: 为何 libncursesw.so.6 依赖 libtinfo.so.6, 而非对应的 libtinfow.so.6 ?

#3

帖子 offline » 2023-04-25 13:33

astolia 写了: 2023-04-24 11:40 因为libtinfo6包里面的libtinfo.so.6就是带--enable-widec编译出来的,也就是你说的libtinfow.so.6

至于ABI,建议你在下“不兼容”的结论前,先去看看它的符号表,查一下对应函数的定义





我可没下结论说“一定不兼容”,原话“Debain 对 ncurses 做的这种改动应该会导致 ABI 不兼容吧?” 是觉得有可能,没下定论吧?

但你这么一说,我就觉得应该亲自测试一下。发现果然不兼容,会导致程序崩溃。用具体的例子来说明,如果你不信可以照着做。


从这个:

https://opensuse.pkgs.org/15.4/opensuse ... 4.rpm.html

可以看出: Suse 发行版同时提供 libtinfo.so.6 和 libtinfow.so.6, 它将“非宽版”和“宽版”的 libtinfo 分开,而 Debian/Ubuntu 和 Arch 等诸多发行版只提供 libtinfo.so.6, 将“非宽版”和“宽版”合并在一起。

如果自己编译 ncurses, 简单地使用 --with-termlib 选项,那么就得到 Suse 一样的结果。即:用了 --enable-widec 选项就生成 libtinfow.so.6, 没有该选项就生成 libtinfo.so.6. 而如果像 Debian/Ubuntu 那样用 --with-termlib=tinfo 将“非宽版”和“宽版”都使用 libtinfo.so.6 的 soname, 内在却是 libtinfow.so.6, 那么系统内使用完全正常。因为 ibtinfow.so.6 是 libtinfo.so.6 的超集,前者可以取代后者。


不兼容的问题来了,如果在 Debian/Ubuntu 上编译一个宽版的 ncurses 应用程序,那么它将依赖 libncursesw.so.6 和 libtinfo.so.6, 将二进制文件拿到 Suse 上去执行会怎样呢?我这里没有 Suse 的环境,只有 Debian/Ubuntu 环境。不过可以试着模拟,将 Suse 的 RPM 包下载并且解压出来,然后通过 LD_LIBRARY_PATH 环境变量让该宽版 ncurses 应用程序调用 Suse 的库。结果运行不起来,提示缺少相关符号。但这并没测试出结果来,因为根据提示信息应该是 Suse 的 库少了其他东西。

然后我在 Debian/Ubuntu 系统下自己编译 ncurses-6.4, 分别使用 --with-termlib 和 --with-termlib --enable-widec 生成“非宽版”和“宽版”的库。再通过 LD_LIBRARY_PATH 环境变量运行,运行起来了!当然出错了!提示 Segmentation fault 因为这时的 libtinfo.so.6 是“非宽版”,而“非宽版”无法反过来兼容“宽版”。


结论:将 Debian/Ubuntu 上编译的宽版 ncurses 应用程序拿到类似于 Suse 的环境去运行会导致程序崩溃。如果反过来,将 Suse 上编译的宽版 ncurses 应用程序拿到 Debian/Ubuntu 的环境去运行,当然也会出错。只不过并非程序崩溃,而是根本无法运行,因为缺少 libtinfow.so.6. 这点已经有许多人反馈过:

Error while laoding shared libraries: libtinfow.so.6
https://github.com/karlstav/cava/issues/232
回复