我不知道如何解决它,而不尝试随机的事情。任何帮助都非常感谢。
在你的平台上构建 Readline 的方法被打破了。以下是技术细节......共享对象缺少符号,这没关系:
$ ldd -r -d /usr/local/lib/libreadline.so
linux-vdso.so.1 (0x00007ffea672a000)
libc.so.6 => /lib64/libc.so.6 (0x00007fec922eb000)
/lib64/ld-linux-x86-64.so.2 (0x00007fec92521000)
undefined symbol: UP (/usr/local/lib/libreadline.so)
undefined symbol: PC (/usr/local/lib/libreadline.so)
undefined symbol: BC (/usr/local/lib/libreadline.so)
undefined symbol: tputs (/usr/local/lib/libreadline.so)
undefined symbol: tgoto (/usr/local/lib/libreadline.so)
undefined symbol: tgetflag (/usr/local/lib/libreadline.so)
undefined symbol: tgetent (/usr/local/lib/libreadline.so)
undefined symbol: tgetnum (/usr/local/lib/libreadline.so)
undefined symbol: tgetstr (/usr/local/lib/libreadline.so)
实际上,我认为构建应该由于缺少符号而失败。但是维护者不这么认为,他更愿意将他的痛苦和痛苦传播给他图书馆的用户。
缺少的符号是 Ncurses 和 Terminfo 的一部分,但缺少链接库。那不行。链接库应该类似于libtinfo.so
orlibtinfow.so
但它缺少:
$ ldd /usr/local/lib/libreadline.so
linux-vdso.so.1 (0x00007ffd535cb000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3a5183c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3a520b5000)
这里是和朋友所在的位置UP
:PC
$ nm -D /usr/local/lib/libtinfow.so | grep -E 'UP|PC'
000000000023797e B PC
0000000000237968 B UP
您应该能够在 Readline 配置期间添加-ltinfo
或添加-ltinfow
到您的LIBS
/LDLIBS
中,但这不起作用。添加-ltinfo
或被-ltinfow
忽略。
实践中的修复是修补 Readline makefile,然后从源代码构建 Ncurses 和 Readline。
这是 Readline 补丁的样子。该补丁是使用以下内容创建的diff -u
:
--- shlib/Makefile.in
+++ shlib/Makefile.in
@@ -174,11 +174,11 @@
$(SHARED_READLINE): $(SHARED_OBJ)
$(RM) $@
- $(SHOBJ_LD) ${SHOBJ_LDFLAGS} ${SHLIB_XLDFLAGS} -o $@ $(SHARED_OBJ) $(SHLIB_LIBS)
+ $(SHOBJ_LD) ${SHOBJ_LDFLAGS} ${SHLIB_XLDFLAGS} -o $@ $(SHARED_OBJ) $(SHLIB_LIBS) -ltinfo
$(SHARED_HISTORY): $(SHARED_HISTOBJ) xmalloc.so xfree.so
$(RM) $@
- $(SHOBJ_LD) ${SHOBJ_LDFLAGS} ${SHLIB_XLDFLAGS} -o $@ $(SHARED_HISTOBJ) xmalloc.so xfree.so $(SHLIB_LIBS)
+ $(SHOBJ_LD) ${SHOBJ_LDFLAGS} ${SHLIB_XLDFLAGS} -o $@ $(SHARED_HISTOBJ) xmalloc.so xfree.so $(SHLIB_LIBS) -ltinfo
# Since tilde.c is shared between readline and bash, make sure we compile
# it with the right flags when it's built as part of readline
修复 makefile 并构建 Ncurses 和 Readline 后,您的链接库将包括libtinfo.so
. 狗屎将不再被打破。通知libtinfo.so
链接如下。
$ ldd /usr/local/lib/libreadline.so
linux-vdso.so.1 (0x00007ffd535cb000)
libtinfow.so.6 => /usr/local/lib/libtinfow.so.6 (0x00007f3a51c2d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3a5183c000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3a520b5000)
现在,正确配置 Ncurses 可能会很棘手。那是因为所有库都有一个非宽版本和宽版本。Ncurses 中有 6 个类似的东西:
$ ls /usr/local/lib/lib*w\.so*
/usr/local/lib/libformw.so /usr/local/lib/libncursesw.so.6
/usr/local/lib/libformw.so.6 /usr/local/lib/libncurses++w.so.6.1
/usr/local/lib/libformw.so.6.1 /usr/local/lib/libncursesw.so.6.1
/usr/local/lib/libmenuw.so /usr/local/lib/libpanelw.so
/usr/local/lib/libmenuw.so.6 /usr/local/lib/libpanelw.so.6
/usr/local/lib/libmenuw.so.6.1 /usr/local/lib/libpanelw.so.6.1
/usr/local/lib/libncurses++w.so /usr/local/lib/libtinfow.so
/usr/local/lib/libncursesw.so /usr/local/lib/libtinfow.so.6
/usr/local/lib/libncurses++w.so.6 /usr/local/lib/libtinfow.so.6.1
我使用配置选项构建了 Ncurses的广泛--enable-widec
版本。--enable-widec
被描述为:
此开关导致构建宽字符库(例如 libncursesw.so.6.2)而不是普通库(例如 libncurses.so.6.2)。这些宽字符库可用于多字节和传统的 8 位语言环境,而普通库只能在 8 位语言环境中正常工作。宽字符库和普通库是源代码兼容的,但不是二进制兼容的。
如果您使用 配置 Ncurses --enable-widec
,那么您将libtinfow.so
用作 Readline 的链接库。如果您使用非宽版本,那么您将libtinfo.so
用作 Readline 的链接库。
如果你用 配置 Ncurses --enable-widec
,那么你应该用 配置你的宽 Readline --enable-multibyte
。如果您从源代码构建 Bash 并使用广泛的 Readline,那么您应该使用--enable-multibyte
. 你要注意细节...
不,同一选项的不同标志 ---enable-widec
和--enable-multibyte
- 是正确的。当您可以添加混乱时,为什么要保持一致?
你可以感谢维护 Ncurses 和 Readline 的人来解决这个问题。他不遵循标准的 GNU 工作流程或 Linux 最佳实践。我鄙视与他坚持的废话一起工作。您将浪费数小时试图弄清楚如何做一些应该简单的事情,例如使用哪些选项,或者让 Readline 使用正确的链接库,或者获得像 BC 或 OpenLDAP 这样的依赖项来正确构建。
另一个宝石是内存泄漏。如果您不幸在 Android 上需要它,那么您可以指望资源耗尽,因为库泄漏了太多内存。Android 通过 JNI 将加载和卸载共享对象数千次,并且由于累积的内存泄漏,您将内存不足。
最后,Ncurses 和 Readline 没有公开的 repo。没有办法针对他的来源提出拉取请求或提供补丁。他的想法git pull
是这样的废话:应用补丁。