4

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

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

如果我让他们重新编译代码,一切都很好。通过环顾四周,我发现这是 libtinfo 和 libncurses 之间分离的问题。它可以通过制作几个 simlink 来解决,但它只有在用户具有 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)
4

2 回答 2

6

在您编译的程序上执行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以便链接器不需要为您的程序添加依赖项。LDFLAGSlibtinfolibtinfo

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

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

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

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

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

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

于 2013-04-03T22:31:12.597 回答
2

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

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

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

并再次编译:

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

这个想法来自以下 Launchpad 网站

于 2017-01-07T03:13:34.227 回答