在可执行文件的同一目录中找不到.so

我有一个需要dynamic链接libtest.so的可执行文件,所以我把它们放在同一个目录下,然后:

 cd path_to_dir ./binary 

但是得到了这个:

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

如何找不到与可执行文件本身在同一目录中的libtest.so

除非通过$LD_LIBRARY_PATH明确指向加载器,否则加载器从不检查当前目录中的共享对象。 有关更多详细信息,请参阅ld.so(8)手册页。

虽然你可以设置LD_LIBRARY_PATH让dynamic链接器知道在哪里看,有更好的select。 您可以将共享库置于其中一个标准位置,请参阅/etc/ld.so.conf (在Linux上)和/usr/bin/crle (在Solaris上)以获取这些位置的列表

在构build二进制文件时,可以将-R <path>传递给链接器,这会将<path>添加到为共享库扫描的目录列表中。 这是一个例子。 首先,显示问题:

libtest.h:

 void hello_world(void); 

libtest.c:

 #include <stdio.h> void hello_world(void) { printf("Hello world, I'm a library!\n"); } 

hello.c中:

 #include "libtest.h" int main(int argc, char **argv) { hello_world(); } 

Makefile(必须使用制表符):

 all: hello hello: libtest.so.0 %.o: %.c $(CC) $(CFLAGS) -fPIC -c -o $@ $< libtest.so.0.0.1: libtest.o $(CC) -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.1 libtest.o libtest.so.0: libtest.so.0.0.1 ln -s $< $@ clean: rm -f hello libtest.o hello.o libtest.so.0.0.1 libtest.so.0 

让我们来运行它:

 $ make cc -fPIC -c -o libtest.o libtest.c cc -shared -Wl,-soname,libtest.so.0 -o libtest.so.0.0.1 libtest.o ln -s libtest.so.0.0.1 libtest.so.0 cc hello.c libtest.so.0 -o hello $ ./hello ./hello: error while loading shared libraries: libtest.so.0: cannot open shared object file: No such file or directory 

如何解决它? 将-R <path>添加到链接器标志(在这里,通过设置LDFLAGS )。

 $ make clean (...) $ make LDFLAGS="-Wl,-R -Wl,/home/maciej/src/tmp" (...) cc -Wl,-R -Wl,/home/maciej/src/tmp hello.c libtest.so.0 -o hello $ ./hello Hello world, I'm a library! 

看看二进制文件,你可以看到它需要libtest.so.0

 $ objdump -p hello | grep NEEDED NEEDED libtest.so.0 NEEDED libc.so.6 

除了标准位置之外,二进制文件将在指定的目录中查找它的库:

 $ objdump -p hello | grep RPATH RPATH /home/maciej/src/tmp 

如果您希望二进制文件查看当前目录,则可以将RPATH设置为$ORIGIN 。 这有点棘手,因为你需要确保美元符号不被make解释。 以下是一种方法:

 $ make CFLAGS="-fPIC" LDFLAGS="-Wl,-rpath '-Wl,\$\$ORIGIN'" $ objdump -p hello | grep RPATH RPATH $ORIGIN $ ./hello Hello world, I'm a library! 

要从与您的可执行文件相同的目录加载共享对象,只需执行:

 $ LD_LIBRARY_PATH=. ./binary 

注意:它不会修改您的系统的LD_LIBRARY_PATHvariables。 改变只影响到这一点,只有这一点,执行你的程序。

对于那些还没有回答的人来说,我发现自己有以下的build议:

您可以尝试使用以下sudo ldconfig -v更新ld.so.cache: sudo ldconfig -v

为我工作。