Linux

在與執行檔相同的目錄中找不到 .so?

  • December 31, 2021

我有一個需要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與執行檔本身在同一目錄中的文件?

載入器從不檢查目前目錄中的共享對象,除非它被明確定向到 via $LD_LIBRARY_PATH。有關更多詳細資訊,請參見ld.so(8)手冊頁。

雖然您可以設置 LD_LIBRARY_PATH 讓動態連結器知道在哪裡查找,但還有更好的選擇。您可以將共享庫放在標準位置之一,請參閱/etc/ld.so.conf(在 Linux 上)和/usr/bin/crle(在 Solaris 上)以獲取這些位置的列表

您可以-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");
}

你好ç:

#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!

引用自:https://serverfault.com/questions/279068