Gcc

如何使用相對路徑連結到共享庫?

  • November 2, 2018

ld.so(8) 的手冊頁中,它說

解析庫依賴項時,動態連結器首先檢查每個依賴項字元串以查看它是否包含斜杠(如果在連結時指定了包含斜杠的庫路徑名,則會發生這種情況)。如果找到斜線,則依賴字元串被解釋為(相對或絕對)路徑名,並使用該路徑名載入庫。

如何gcc連結到帶有斜杠路徑的庫?我已經嘗試過,-l但這似乎只適用於用於搜尋各種路徑的庫名稱,而不是路徑參數本身。

一個後續問題:當以這種方式連結到相對路徑時,相對路徑是什麼(例如包含二進製文件的目錄或執行時的工作目錄)?

我在搜尋時找到的所有連結指南都​​使用RPATHLD_LIBRARY_PATHRUNPATH. RPATH已棄用,大多數討論不鼓勵使用LD_LIBRARY_PATH. RUNPATH以 開頭的路徑$ORIGIN允許連結到相對路徑,但它有點脆弱,因為它可以被LD_LIBRARY_PATH. 我想知道相對路徑是否會更健壯(因為我找不到任何討論這個的東西,我猜不是,可能是因為路徑是相對於執行時目錄的)。

如果我們(暫時)忽略gcc問題的或連結部分,而是patchelf在 linux 系統上修改二進製文件

$ ldd hello
       linux-vdso.so.1 =>  (0x00007ffd35584000)
       libhello.so.1 => not found
       libc.so.6 => /lib64/libc.so.6 (0x00007f02e4f6f000)
       /lib64/ld-linux-x86-64.so.2 (0x00007f02e533c000)
$ patchelf --remove-needed libhello.so.1 hello
$ patchelf --add-needed ./libhello.so.1 hello
$ ldd hello
       linux-vdso.so.1 =>  (0x00007ffdb74fc000)
       ./libhello.so.1 => not found
       libc.so.6 => /lib64/libc.so.6 (0x00007f2ad5c28000)
       /lib64/ld-linux-x86-64.so.2 (0x00007f2ad5ff5000)

我們現在有一個帶有相對路徑庫的二進製文件,如果存在合適的目錄,其中存在libhello.so.1文件

$ cd english/
$ ../hello
hello, world
$ cd ../lojban/
$ ../hello
coi rodo

我們發現路徑是相對於程序的工作目錄的,這就帶來了各種各樣的問題,尤其是安全 問題。這可能有一些生產用途,也許可以測試不同版本的庫。編譯兩個不同的二進製文件可能會更簡單,或者patchelf在必要的庫中編譯而不需要相對工作目錄的複雜性。

編譯步驟

libhello只有一個helloworld電話

$ cat libhello.c
#include <stdio.h>
void helloworld(void)
{
   printf("coi rodo\n");
}

並通過編譯

CFLAGS="-fPIC" make libhello.o
gcc -shared -fPIC -Wl,-soname,libhello.so.1 -o libhello.so.1.0.0 libhello.o -lc
ln -s libhello.so.1.0.0 libhello.so.1
ln -s libhello.so.1.0.0 libhello.so

並且hello進行呼叫的那個helloworld是通過編譯的

$ cat hello.c
int main(void)
{
   helloworld();
   return 0;
}
$ CFLAGS="-lhello -L`pwd`/english" make hello

沒有更新檔

事後看來,修改gcc命令以使用相對目錄路徑:

$ gcc -shared -fPIC -Wl,-soname,./libhello.so.1 -o libhello.so.1.0.0 libhello.o -lc
$ cd ..
$ rm hello
$ CFLAGS="-lhello -L`pwd`/lojban" make hello
$ ldd hello | grep hello
       ./libhello.so.1 => not found
$ english
$ ../hello
hello, world

以正常方式編譯庫,然後根據需要使用patchelf.

引用自:https://unix.stackexchange.com/questions/479421