【问题标题】:C code with ncurses compiled with libtinfo dependency使用 libtinfo 依赖项编译的带有 ncurses 的 C 代码
【发布时间】:2013-04-03 21:16:40
【问题描述】:

我最近在 Linux 上使用 ncurses 用 C 语言编写了一个扫雷器实现;在我的电脑上一切正常,但如果我尝试将编译后的二进制文件提供给其他人,他们经常会收到错误:

error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory

如果我让他们重新编译代码,一切都很好。通过环顾四周,我发现这是 libtinfo 和 libncurses 之间分离的问题。可以通过几个simlinks来解决,但是这个解决方案只有在用户有root权限的情况下才可行。

截至此处(和其他来源)http://www.cyberspice.org.uk/blog/2009/12/24/tinfo-about-dash/,似乎可以通过以不同方式编写代码或以不同方式编译来解决这个问题。我宁愿能够以这种方式解决问题,也不愿强迫人们制作 simlink。

在正确方向上的任何指示以了解如何解决我的问题?如果需要,我可以添加任何代码或细节,但发布所有内容似乎有点过头了,所以请告诉我可以添加什么(如果需要)以更好地理解问题。

我现在唯一发布的是makefile:

CC=gcc -std=gnu89 -pedantic -Wall -Wno-unused-but-set-variable
CFLAGS=-c -g
LDFLAGS=-lncurses

NAME=campo_ex
OBJECTS=error.o interface.o utilities.o main.o grid.o

DEBUG_NAME=debug
DEBUG_OBJECTS=error.o interface.o utilities.o debug.o

$(NAME): $(OBJECTS)
    $(CC) -o $(NAME) $(OBJECTS) $(LDFLAGS)

main.o: main.c interface.h grid.h
    $(CC) $(CFLAGS) main.c

debug.o: debug.c interface.h
    $(CC) $(CFLAGS) debug.c

error.o: error.c error.h
    $(CC) $(CFLAGS) error.c

utilities.o: utilities.c utilities.h
    $(CC) $(CFLAGS) utilities.c

interface.o: interface.c interface.h error.h utilities.h
    $(CC) $(CFLAGS) interface.c

grid.o: grid.c grid.h error.h
    $(CC) $(CFLAGS) grid.c

.PHONY: clean
clean:
    @-rm -f $(OBJECTS) $(NAME) $(DEBUG_NAME) $(DEBUG_OBJECTS)

.PHONY: debug
debug: $(DEBUG_OBJECTS)
    $(CC) -o $(DEBUG_NAME) $(DEBUG_OBJECTS) $(LDFLAGS)

【问题讨论】:

  • 如果你真的想分发二进制文件,你可以静态链接可执行文件,这样你就不会遇到任何共享库问题。
  • 我想避免额外的空间,但它肯定是一个可行的选择。

标签: c linux ncurses


【解决方案1】:

在已编译的程序上执行readelf -d 可能会显示与 libtinfo.so.5 的连接

$ readelf -d /path/to/your/program  | grep NEEDED
[...]
0x0000000000000001 (NEEDED)             Shared library: [libtinfo.so.5]
[...]

这可能会被拉入,因为您的libncurses.so 以某种方式将其拉入,例如通过包含以下内容:

INPUT(... -ltinfo)

(或类似的东西。我只能在这里猜测..)

您可以尝试将-Wl,--as-needed 添加到您的LDFLAGS,并希望您的程序没有直接引用来自libtinfo 的任何符号,这样链接器就不需要为您的程序添加libtinfo 的依赖项。

LDFLAGS=-Wl,--as-needed -lncurses

用新的LDFLAGS 重新编译,然后用readelf -d 再次检查它是否编译和链接没有错误。

如果libncurses 使用来自libtinfo 的符号但不包含对libtinfo 本身的依赖,则使用--as-needed 可能会出现问题。如果发生这种情况,您的构建将失败并抱怨unreferenced symbols 或类似的......

因此,如果这不起作用,您可能需要修复您的 curses 安装或使用您已经提到的(在我看来非常肮脏的)符号链接黑客。或者让用户在他们的系统上编译代码 - 如果您不想共享代码,您也可以在目标系统上进行链接。

要修复 symlink-need-root-privileges 问题,您还可以在链接器标志中添加 -Wl,-rpath,'$ORIGIN/../lib' 并扩展程序的库搜索路径。这使用户能够将您的二进制文件安装到/home/user/bin/program 并在/home/user/bin/../lib 中搜索库。所以他们可以在/home/user/lib 中进行“肮脏”的符号链接黑客攻击。

仅分发二进制文件时总是有问题。

【讨论】:

  • 链接器的附加标志起到了作用。关于特权部分的好主意,没想到。如果我需要它,我一定会记住的。谢谢!
【解决方案2】:

我有同样的问题。经过大量搜索,我意识到问题的原因是libtinfo 功能现在嵌入在libncurses 库中。

您可以通过执行以下 2 个简单步骤来解决它:

  1. 转到您的 libncurses 共享库所在的目录(通常在您的工具链中)
  2. 创建以下链接

然后再次编译:

sudo ln -s libncurses.so.6 libtinfo.so.6  
sudo ln -s libncurses.so.6 libtinfo.so

这个想法来自the following Launchpad site

【讨论】:

  • OP 的问题是关于不同的东西(这个答案是行不通的)。
  • 哇。很棒的发现。
猜你喜欢
  • 2019-06-01
  • 2016-05-26
  • 2017-10-21
  • 1970-01-01
  • 2020-02-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多