Linux下動態共享庫載入時的搜尋路徑詳解

2021-06-18 00:39:40 字數 2378 閱讀 6775

對動態庫的實際應用還不太熟悉的讀者可能曾經遇到過類似「error while loading shared libraries」這樣的錯誤,這是典型的因為需要的動態庫不在動態鏈結器ld.so的搜尋路徑設定當中導致的。

1.elf可執行檔案中動態段中dt_rpath所指定的路徑。這實際上是通過一種不算很常用,卻比較實用的方法所設定的:編譯目標**時,可以對gcc加入鏈結引數「-wl,-rpath」指定動態庫搜尋路徑;

2.環境變數ld_library_path指定的動態庫搜尋路徑;

3./etc/ld.so.cache中所快取的動態庫路徑(如果支援ld.so.cache的話)。這可以通過修改配置檔案/etc/ld.so.conf中指定的動態庫搜尋路徑來改變;

4.預設的動態庫搜尋路徑/lib;

5.預設的動態庫搜尋路徑/usr/lib。 

在嵌入式linux系統的實際應用中,1和2被經常使用,也有一些相對簡單的的嵌入式系統會採用4或5的路徑來規範動態庫。3在嵌入式系統中使用的比較少,因為有很多系統根本就不支援ld.so.cache。

4和5的方式非常簡單,只要將所需要的庫放到/lib或/usr/lib就可以解決找不到庫的問題,不過對於大一些的系統來說,不太方便管理。1和2的方式要稍微複雜一些,下面我們用乙個非常簡單的例子來說明如何應用。

首先編寫乙個最簡單的動態共享庫,源**pirnt.c如下:

1 #include

2 3 void print_foo()

4 注意將它編譯成共享庫:

# gcc print.c -shared -o libprint.so

# file libprint.so

libprint.so: elf 32-bit lsb shared object, intel 80386, version 1 (sysv), not stripped

呼叫該共享庫main.c**如下:

1 #include

2 3 extern void print_foo();

4 5 int main()

6 編譯之後的執行結果如下:

# gcc main.c -l./ -lprint -o pfoo

# ./pfoo

./pfoo: error while loading shared libraries: libprint.so: cannot open shared object file: no such file or directory

這便是典型的找不到動態庫的錯誤。通常我們可以通過設定環境變數ld_library_path來指定動態庫的搜尋路徑(即上面的方法2),比如這樣就可以正確執行了:

# export ld_library_path=./

# ./pfoo

fooooooooo

但這種方法有乙個明顯的缺點:一旦ld_library_path被設定,則在這個環境變數生效的範圍之內,所有其他的elf可執行程式也會按照這個順序去搜尋動態庫,這樣勢必會造成搜尋時的一些浪費。

我們也可以使用另外一種方案來解決這種問題,即利用引數「-wl,-rpath」在編譯時指定執行時的搜尋路徑(即上面的方法1),如下所示:

# unset ld_library_path

# echo $ld_library_path

# gcc main.c -l./ -lprint -o pfoo_r -wl,-rpath=./

# ./pfoo

./pfoo: error while loading shared libraries: libprint.so: cannot open shared object file: no such file or directory

# ./pfoo_r

fooooooooo

我們首先unset了ld_library_path,可以看到它已經不再有效了(當然這不是使用引數「-wl,-rpath」的必要步驟,在這裡只是為了說明它已經不再起作用了),而且」pfoo」程式執行時也會發生找不到庫的錯誤,而我們加入編譯引數「-wl,-rpath,./」之後得到的pfoo_r程式則能正常執行。

事實上我們可以通過readelf工具來檢視兩個檔案的差異:

比較 # readelf -d pfoo  與#readelf -d pfoo_r

「readelf -d」可以用來檢視elf檔案的動態節(dynamic section)。對比pfoo 和pfoo_r的結果我們可以發現,pfoo_r中多出來了rpath項,指定」library rpath: [./]」。通過這種方式,我們可以用非常小的代價(僅增加幾乎可以忽略的空間開銷),對每個elf檔案都指定最優化的搜尋路徑,達到提公升效能的目的。這是我們比較推薦的一種方法。當然了,具體如果操作依賴於具體的軟體系統的情況,簡單的系統中直接將所有的庫都放到/lib下也未嘗不是一種簡單易行的優化方案。

**:

Linux下動態共享庫載入時的搜尋路徑詳解

對動態庫的實際應用還不太熟悉的讀者可能曾經遇到過類似 error while loading shared libraries 這樣的錯誤,這是典型的因為需要的動態庫不在動態鏈結器ld.so的搜尋路徑設定當中導致的。具體說來,動態鏈結器ld.so按照下面的順序來搜尋需要的動態共享庫 1 elf可執行...

Linux下動態共享庫載入時的搜尋路徑詳解

對動態庫的實際應用還不太熟悉的讀者可能曾經遇到過類似 error while loading shared libraries 這樣的錯誤,這是典型的因為需要的動態庫不在動態鏈結器ld.so的搜尋路徑設定當中導致的。具體說來,動態鏈結器ld.so按照下面的順序來搜尋需要的動態共享庫 1 elf可執行...

linux共享庫動態載入

首先設想一種情況,我們需要將某個功能做成可配置的,比如近期再弄的圖形系統,風格應該是可配置的 在配置檔案中用字串記錄使用到的 畫法 庫 這個 畫法 就比如windows裡面的開始按鈕,windows經典 風格是乙個矩形,而 windows xp 風格則是乙個圓角矩形,它們使用的繪圖方法當然不一樣 改...