載入相對於可執行路徑的共享對象

載入相對於可執行路徑的共享對象

我正在嘗試讓 C 應用程式從相對目錄加載共享對象,無論我從哪裡調用它。到目前為止,只有當我調用它時與可執行檔位於同一目錄中時,它才有效:

~/prog$ ./my_program
Success
~/prog$ cd ..
~$ ./prog/my_program
./prog/my_program: error while loading shared libraries: libs/libmysharedobject.so: cannot open shared object file: No such file or directory

從上面的輸出可以猜到,共享物件儲存在該~/prog/libs/目錄下。以下是相關 gcc 呼叫的樣子:

gcc -std=c99 -ggdb -Wall -pedantic -Isrc
    -fPIC -shared -Wl,-soname,libs/libmysharedogbject.so
    -o libs/libmysharedobject.so libs/mysharedobject.c
[...]
gcc [CFLAGS omitted] -o my_program main.c
    build/src/my_program.o build/src/common.o
    -lm -Llibs -lmysharedobject

這是輸出的頂部readelf -d my_program

Dynamic section at offset 0x6660 contains 26 entries:
  Tag        Type                         Name/Value
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libs/libmysharedobject.so]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

我嘗試添加-Wl,-z,origin,-rpath='$ORIGIN',這會導致以下幾行顯示在readelf的輸出中:

 0x000000000000000f (RPATH)              Library rpath: [$ORIGIN]
[...]
 0x000000006ffffffb (FLAGS_1)            Flags: ORIGIN

但這似乎並不能解決我的問題。我也嘗試過設定rpath$ORIGIN/libs.、 和./libs,但都無濟於事。 (更新:$(CURDIR)也沒有任何效果。這讓我感到驚訝,因為它擴展為絕對路徑。)

有沒有辦法讓我的可執行檔找到它的共享對象,而不管它是從哪個目錄調用的,最好不要LD_LIBRARY_PATH每次都讓最終用戶設定?或者我正在嘗試做一些 Linux 不支援的事情?

答案1

將 rpath 設定為 $ORIGIN/libs 並將 soname 設定為 libsharedobject 而不是 libs/libsharedobject。我的 makefile 如下。

all: my_program

libs/libmysharedobject.so: Makefile success.c
  gcc -fPIC -shared -Wl,-soname,libmysharedobject.so \
    -o libs/libmysharedobject.so success.c

my_program: Makefile libs/libmysharedobject.so
  gcc -o my_program main.c -Llibs -lmysharedobject -Wl,-R,'$$ORIGIN/libs'

相關內容