使用libtinfo依赖编译的ncurses的C代码

gca*_*ali 4 c linux ncurses

我最近在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/,似乎这是一个可以通过编写代码来解决的问题以不同的方式或可能以不同的方式编译.我宁愿能够解决问题,而不是强迫人们制作simlinks.

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

我现在唯一发布的是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)
Run Code Online (Sandbox Code Playgroud)

mar*_*iux 5

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

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

这可能是因为你libncurses.so以某种方式拉动它,例如通过包含以下内容:

INPUT(... -ltinfo)
Run Code Online (Sandbox Code Playgroud)

(或类似的东西.我可以猜到这里..)

您可以尝试添加-Wl,--as-needed到您LDFLAGS的程序,并希望您的程序不libtinfo直接引用任何符号,以便链接器不需要为程序添加依赖项libtinfo.

LDFLAGS=-Wl,--as-needed -lncurses
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

仅在分发二进制文件时始终存在问题.