天天看點

linux 配置和加載動态庫 ldconfig

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下進行連結的預設操作是先考慮動态連結庫,即如果同時存在靜态和動态庫,不特别指定的話,将與動态庫相連接配接。

繼續閱讀