本文**:
linux指定動態庫路徑
linux指定動態庫路徑包括:1.指定編譯時動態庫路徑;2.指定執行時動態庫路徑。後文提到的動態庫路徑都是指的是這兩種路徑。
眾所周知,linux動態庫的預設搜尋路徑是/lib和/usr/lib
(不管是編譯還是執行都會預設搜尋這兩個路徑)
在linux 中,動態庫的搜尋路徑除了預設的搜尋路徑外,還可以通過以下三種方法來指定。
1.在配置檔案/etc/ld.so.conf中指定動態庫搜尋路徑。
可以通過編輯配置檔案/etc/ld.so.conf來指定動態庫的搜尋路徑,該檔案中每行
是乙個動態庫搜尋路徑。每次編輯完該檔案後,都必須執行命令ldconfig使修改後的配置生效。
以動態庫的建立與使用為例:
//so_test.h
#include "stdio.h"
void test_a();
void test_b();
void test_c();
//test_a.c
#include "so_test.h"
void test_a()
//test_b.c
#include "so_test.h"
void test_b()
//test_c.c
#include "so_test.h"
void test_c()
測試程式
#include 「so_test.h」
int main()
操作過程:
我們通過以下命令用源程式
test_a.c、test_b.c、t
est_c
.c來建立動態庫 libtest.so。
# gcc -c test_a.c
test_b.c
test_c.c
# gcc
-shared
-fpic -o libtest.so *.o
或者直接一條指令:
#gcc -shared -fpic -o libtest.so test_a.c test_b.c test_c.c
這樣在當前目錄下就生成了動態庫libtest.so
。對於標頭檔案位置的存放請參考博文《
linux
標頭檔案》。
注意:-fpic引數宣告鏈結庫的**段是可以共享的
;-shared引數宣告編譯為共享庫。
請注意這次我們編譯的共享庫的名字叫做libtest.so,這也是linux共享庫的乙個命名的慣例了:字尾使用so,而名稱使用lib***x格式。
接著通過以下命令編譯
test
.c,生成目標程式main。
# gcc -o main -l. –ltest
test.c
當應用程式呼叫動態庫的時候,要用-l選項,指定所呼叫的庫名。用-l選項指定庫所在的路徑(如果沒有使用後文所述的三種方法處理的情況下,用這種方式指定庫所在路徑)。
(注意:此時,標頭檔案以及庫檔案都在當前目錄下)
在當前目錄下生成可執行檔案main
執行程式main
#./main
./main: error while loading shared libraries: libtest.so: cannot open shared object file: no such file or directory
出錯了,系統未找到動態鏈結庫libtest.so。原因是系統會預設的到/lib或/usr/lib中尋找需要的庫,但是我們需要的庫放在了當前的目錄下,也就說雖然編譯的時候指定了所需要的動態庫,但是執行的時候並不會到之前編譯時指定的動態庫的位置去尋找動態庫,這也就是為什麼在文章開頭講清楚,什麼是
指定編譯時動態庫路徑
,什麼是
指定執行
時動態庫路徑
。解決的方法就是找到動態庫。怎樣找到動態庫呢?最簡單的解決的方法是將動態庫拷貝到/lib或/usr/lib目錄下,這樣在編譯時不需要指定動態庫的路徑,執行時也不會找不到動態庫(不管編譯還是執行都會到
/lib或/usr/lib
目錄下尋找動態庫)。對於編譯階段找到動態庫的方法還有上面的通過-l選項指定動態庫的路徑。對於執行階段是否可以通過選項指定動態庫,下面的方法3會有介紹。除了上面提到的方法外,我們更需要這樣一種解決思路:我們可以靈活的指定動態庫的存放的位置,然後由作業系統負責動態庫的查詢。當然強大的linux提供了這樣的功能,並且這種功能的實現不止一種,詳細內容可以參考博文《/etc/ld.so.conf檔案》。現在簡單介紹/etc/ld.so.conf的使用,我們打算將製作好的動態庫放在/root/lib目錄下,因此執行如下命令:
# mkdir /root/lib
# mv libtest.so /root/lib/libtest.so
最後編輯配置檔案/etc/ld.so.conf,在該檔案中追加一行/root/lib。
執行程式
main
# ./main
./main: error while loading shared libraries: lib_test.so: cannot open shared object file: no such file or directory
仍然出錯,系統未找到動態庫libtest.so。找找原因,原來在編輯完配置檔案/etc/ld.so.conf後,沒有執行命令ldconfig,所以剛才的修改還未生效。我們執行ldconfig後再試試。
# ldconfig
# ./main
this is in test_
a...
this is in test_
b...
this is in test_c...
#程式main執行成功,並且列印出正確結果。
2.通過環境變數ld_library_path指定動態庫搜尋路徑。
通過設定環境變數ld_library_path也可以指定動態庫搜尋路徑。當通過該環境變數指定多個動態庫搜尋路徑時,路徑之間用冒號」:」分隔。下面通過例2來說明本方法。
舉乙個例子:
這次我們把上面得到的檔案lib_test.so移動到另乙個地方去,如/root下面,然後設定環境變數ld_library_path找到libtest.so。設定環境變數方法如下:
# export ld_library_path=/root
#然後執行:
#./main.out
this is in test_
a...
this is in test_
b...
this is in test_c...
#注意:設定環境變數ld_library_path=/root是不行的,非得export才行。
這種設定
ld_library_path
環境變數只是臨時性的,下次開啟
ld_library_path
的值會失效,因此可以將環境變數寫入到/etc/bash.bashrc檔案中。
3.在編譯目標**時指定該程式
執行時的動態庫搜尋路徑。
還可以在編譯目標**時指定程式的動態庫搜尋路徑。-wl,表示後面的引數將傳給link程式ld(因為gcc可能會自動呼叫ld)。這裡通過gcc 的引數」-wl,-rpath,」指定
舉乙個例子:
這次我們還把上面得到的檔案libtest.so移動到另乙個地方去,如/root/test/lib下面,
因為我們需要在編譯目標**時指定可執行檔案的動態庫搜尋路徑,所以需要用gcc命令重新編譯源程式
test
.c來生成可執行檔案main。
# gcc -o main -l. –ltest -wl,-rpath
=/root/test/lib
test.c#
執行結果:
# ./main.out
this is in test_
a...
this is in test_
b...
this is in test_c...#
程式./main執行成功。因此程式main搜尋到的動態庫是/root/test/lib/lib_test.so。
關於-wl,rpath的使用方法我再舉乙個例子,應該不難從中看出指定多個路徑的方法:
gcc -wl,-rpath,/home/arc/test,-rpath,/lib/,-rpath,/usr/lib/,-rpath,/usr/local/lib test.c
以上介紹了三種指定動態庫搜尋路徑的方法,加上預設的動態庫搜尋路徑/lib和/usr/lib,共五種動態庫的搜尋路徑,那麼它們搜尋的先後順序是什麼呢?讀者可以用下面的方法來試驗一下:
(1) 用前面介紹的方法生成5個libtest.so放在5個不同的資料夾下面,要求每乙個libtest.so都唯一對應乙個搜尋路徑,並注意main程式輸出的不同。
(2) 執行main,即可看出他是那個搜尋路徑下的,然後刪除這個路徑下的libtest.so,然後再執行。依此類推操作,即可推出搜尋順序。
可以得出動態庫的搜尋路徑搜尋的先後順序是:
1.編譯目標**時指定的動態庫搜尋路徑;
2.環境變數ld_library_path指定的動態庫搜尋路徑;
3.配置檔案/etc/ld.so.conf中指定的動態庫搜尋路徑;
4.預設的動態庫搜尋路徑/lib;
5.預設的動態庫搜尋路徑/usr/lib。
在上述1、2、3指定動態庫搜尋路徑時,都可指定多個動態庫搜尋路徑,其搜尋的先後順序是按指定路徑的先後順序搜尋的。有興趣的讀者自己驗證。
linux指定動態庫路徑
通常有兩種方法 1.把動態庫放到系統庫或者在系統庫中做乙個鏈結,這樣編譯和執行都會去系統庫找。這樣容易引起系統庫混亂。2.export ld library path 指定庫搜尋路徑,但是這樣登出再登陸就沒了。還有第三種方法,編譯時使用 wl,rpath,wl,路徑 這樣就能把路徑編譯到可執行檔案裡...
Linux 指定執行時動態庫路徑
方法一 在配置檔案 etc ld.so.conf 中指定動態庫搜尋路徑。每次編輯完該檔案後,都必須執行命令 ldconfig 使修改後的配置生效。我們通過例 1 來說明該方法。例 1 我們通過以下命令用源程式 pos conf.c 見程式 1 來建立動態庫 libpos.so gcc fpic sh...
Linux下指定動態庫的載入路徑
一 庫檔案的搜尋路徑 2 通過環境變數ld library path指定動態庫搜尋路徑 當通過該環境變數指定多個動態庫搜尋路徑時,路徑之間用冒號 分隔 3 在編譯目標 時指定該程式的動態庫搜尋路徑 還可以在編譯目標 時指定程式的動態庫搜尋路徑。這是通過gcc 的引數 wl,rpath,指定,當指定多...