linux 動態裝載動態庫 ldd,ldconfig,ld.so.conf, ld.so.cache

查志強發表於2014-06-20

【原文:http://blog.csdn.net/jiafu1115/article/details/15808391

前面我們介紹過,GCC編譯C++程式的那些步驟,其中包括編譯的時候include的搜尋目錄,連結的時候庫的搜尋目錄(這裡的庫包含兩種庫)。還有一個時候,需要搜尋路徑,那就是裝載動態庫的時候,這個時候與GCC無關了。而是與linux系統自身有關係。

 

動態轉載動態庫,是為基於動態庫編譯連結而來的可執行程式設定的一個程式執行過程中需要的功能,對於那些只基於靜態庫的可執行程式來說,這個功能沒有什麼用。

 

1)執行這個動作的linux程式:  ld.so

2)這個程式參考的檔案為:/etc/ld.so.conf,該檔案儲存著ld應該搜尋的so檔案路徑。通常ld.so.conf.d這個資料夾下也儲存著分檔案,以供合成ld.so.conf

3)該程式實際參考的檔案為:/etc/ld.so.cache.這個檔案會其實基本上就是對/etc/ld.so.cache 做了稍微的處理利於/usr/bin/ld程式的參考。

4)將/etc/ld.so.conf 更新到/etc/ld.so.cache.的命令: ldconfig. 使用 ldconfig -p|less可以逐步檢視從/usr/bin/ld 眼裡的/etc/ld.so.cache的內容(路徑)。

5)所以往/etc/ld.so.conf內做指定的路徑,如/usr/lib等加入你需要程式搜尋的動態庫.so檔案,不需要執行ldconfig更新。因為/etc/ld.so.cache中儲存的就是目錄,而不是具體的so檔案。

6)向/etc/ld.so.conf新增路徑。則需要呼叫ldconfig來更新/usr/bin/ld的搜尋路徑。


   
ld可以叫靜態聯結器,ld.so可以叫動態聯結器

 

 

執行時動態庫的搜尋路徑:

動態庫的搜尋路徑搜尋的先後順序是:

編譯目的碼時指定的動態庫搜尋路徑(這是通過gcc 的引數"-Wl,-rpath,"指定。當指定多個動態庫搜尋路徑時,路徑之間用冒號""分隔)

環境變數LD_LIBRARY_PATH指定的動態庫搜尋路徑(當通過該環境變數指定多個動態庫搜尋路徑時,路徑之間用冒號""分隔)

配置檔案/etc/ld.so.conf中指定的動態庫搜尋路徑;

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

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

 

也就是說,雖然linux以裝載動態庫時搜尋的路徑以/etc/ld.so.conf為主,但是,仍然有其它的方式,來構建這種裝載路徑的靈活性。仍然是遵守那種先“專”後“寬”的模式去縮短可能的搜尋時間。

第一個,就是在編譯連線該程式的時候,就指定將來需要動態庫的時候搜尋的位置。注意這個與當時的連結路徑雖然有很大的關係,但是他們的概念是不同的。

第二個,也就是在使用/etc/ld.so.conf之前,還有一個路徑設定方法就是環境變數LD_LIBRARY_PATH. 這個東西可以使用:

# export LD_LIBRARY_PATH=”/usr/lib/old:/opt/lib 來建立修改這個變數。

第三個,才是/etc/ld.so.conf

最後。則是系統預設路徑。



(2) 靜態連結庫和動態連結庫的使用區別
首先,回顧一點,一個程式,從原始碼到執行,包括:編譯(compile)、連結(link)、載入(load)、執行(execute),對應的GNU工具一般為:編譯器compiler(gcc)、連結器linker(ld)、載入器loader(其中動態連結庫載入器為ld.so(ld-linux.version.so),在/lib目錄中,如 /lib/ld-linux.so.2,所以不能直接在命令列下執行ld-linux.so,需要完整路徑,載入器一般不需要我們直接執行,在執行可執行程式的載入過程中包含有動態載入的過程)。經常會將編譯和連結統稱為編譯,期間為編譯時(compile time);而載入和執行統稱為執行,期間為執行時或執行時(runtime/execution time)。
靜態連結庫:編譯時(compile time)被使用(更詳細的是連結的時候)。在連結靜態庫的時候,連結器會在其中找到所需要連結的函式,然後將它們拷貝到執行檔案,這種拷貝是完整的拷貝,所以在連結成功後,程式執行不需要靜態庫的參與。
動態連結庫:編譯時和執行時都被使用。在編譯時,連結器在其中找到所需要的函式(或其他物件檔案),生成地址/位置無關程式碼(Position Independent Code (PIC)),並沒有真正的實現拷貝;在執行時(runtime/execution-time),某個程式在執行中要呼叫某個動態連結庫函式的時候,作業系統首先會檢視所有正在執行的程式,看在記憶體裡是否已有此庫函式的拷貝了,如果有,則讓其共享那一個拷貝;只有沒有才連結載入。
說明:Linux下進行連結的預設操作是先考慮動態連結庫,即如果同時存在靜態和動態庫,不特別指定的話,將與動態庫相連線。


相關文章