轉載出處:linux
http://blog.csdn.net/jaylong35/article/details/6132087緩存
1. 鏈接和運行時庫文件搜索路徑到設置
庫文件在鏈接(靜態庫和共享庫)和運行(僅限於使用共享庫的程序)時被使用,其搜索路徑是在系統中進行設置的。通常 Linux 系統把 /lib 和 /usr/lib 兩個目錄做爲默認的庫搜索路徑,因此使用這兩個目錄中的庫時不須要進行設置搜索路徑便可直接使用。對於處於默認庫搜索路徑以外的庫,須要將庫的位置添加到 庫的搜索路徑之中。設置庫文件的搜索路徑有下列兩種方式,可任選其一使用:
(1). 在 /etc/ld.so.conf 文件中添加庫的搜索路徑。(或者在/etc/ld.so.conf.d 下新建一個.conf文件,將搜索路徑一行一個加入-junziyang)
將本身可能存放庫文件的路徑都加入到/etc/ld.so.conf中是明智的選擇添加方法也極其簡單,將庫文件的絕對路徑直接寫進去就OK了,一行一個。例如:
/usr/X11R6/lib
/usr/local/lib
/opt/lib
須要注意的是:這種搜索路徑的設置方式對於程序鏈接時的庫(包括共享庫和靜態庫)的定位已經足夠了,可是對於使用了共享庫的程序的執行仍是不夠的。這是因 爲爲了加快程序執行時對共享庫的定位速度,避免使用搜索路徑查找共享庫的低效率,因此是直接讀取庫列表文件 /etc/ld.so.cache 從中進行搜索的。/etc/ld.so.cache 是一個非文本的數據文件,不能直接編輯,它是根據 /etc/ld.so.conf 中設置的搜索路徑由 /sbin/ldconfig 命令將這些搜索路徑下的共享庫文件集中在一塊兒而生成的(ldconfig 命令要以 root 權限執行)。
所以,爲了保證程序執行時對庫的定位,在 /etc/ld.so.conf 中進行了庫搜索路徑的設置以後,還必需要運行 /sbin/ldconfig 命令更新 /etc/ld.so.cache 文件以後才能夠。ldconfig ,簡單的說,它的做用就是將/etc/ld.so.conf列出的路徑下的庫文件緩存到/etc/ld.so.cache 以供使用。所以當安裝完一些庫文件,(例如剛安裝好glib),或者修改ld.so.conf增長新的庫路徑後,須要運行一下 /sbin/ldconfig使全部的庫文件都被緩存到ld.so.cache中,若是沒作,即便庫文件明明就在/usr/lib下的,也是不會被使用 的,結果編譯過程當中抱錯,缺乏xxx庫,去查看發現明明就在那放着,搞的想大罵computer蠢豬一個。
在程序鏈接時,對於庫文件(靜態庫和共享庫)的搜索路徑,除了上面的設置方式以外,還能夠經過 -L 參數顯式指定。由於用 -L 設置的路徑將被優先搜索,因此在鏈接的時候一般都會以這種方式直接指定要鏈接的庫的路徑。
這種設置方式須要 root 權限,以改變 /etc/ld.so.conf 文件並執行 /sbin/ldconfig 命令。並且,當系統從新啓動後,全部的基於 GTK2 的程序在運行時都將使用新安裝的 GTK+ 庫。不幸的是,因爲 GTK+ 版本的改變,這有時會給應用程序帶來兼容性的問題,形成某些程序運行不正常。爲了不出現上面的這些狀況,在 GTK+ 及其依賴庫的安裝過程當中對於庫的搜索路徑的設置將採用另外一種方式進行。這種設置方式不須要 root 權限,設置也簡單。
(2). 在環境變量 LD_LIBRARY_PATH 中指明庫的搜索路徑。
設置方式:
export LD_LIBRARY_PATH=/opt/gtk/lib:$LD_LIBRARY_PATH
能夠用下面的命令查看 LD_LIBRAY_PATH 的設置內容:
echo $LD_LIBRARY_PATH
至此,庫的兩種設置就完成了。
2.交叉編譯時候如何配置鏈接庫的搜索路徑
交叉編譯的時候不能使用本地(i686機器,即PC機器,研發機器)機器上的庫,可是在作編譯連接的時候默認的是使用本地庫,即/usr/lib, /lib兩個目錄。所以,在交叉編譯的時候,要採起一些方法使得在編譯連接的時候找到須要的庫。
首先,要知道:編譯的時候只須要頭文檔,真正實際的庫文檔在連接的時候用到。 (這是個人理解,假若有不對的地方,敬請網上各位大俠指教) 而後,講講如何在交叉編譯連接的時候找到須要的庫。
(1)交叉編譯時候直接使用-L和-I參數指定搜索非標準的庫文檔和頭文檔的路徑。例如:
arm-linux-gcc test.c -L/usr/local/arm/2.95.3/arm-linux/lib -I/usr/local/arm/2.95.3/arm-linux/include
(2)使用ld.so.conf文檔,將用到的庫所在文檔目錄添加到此文檔中,而後使用ldconfig命令刷新緩存。
(3)使用以下命令:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/arm/2.95.3/arm-linux-lib
參見《ld.so.conf 文檔和PKG_CONFIG_PATH變量》這篇文章。
經過環境變量LD_LIBRARY_PATH指定動態庫搜索路徑(!)。
經過設定環境變量LD_LIBRARY_PATH也能夠指定動態庫搜索路徑。當經過該環境變量指定多個動態庫搜索路徑時,路徑之間用冒號":"分隔。
不過LD_LIBRARY_PATH的設定做用是全局的,過多的使用可能會影響到其餘應用程序的運行,因此多用在調試。(LD_LIBRARY_PATH 的缺陷和使用準則,能夠參考《Why LD_LIBRARY_PATH is bad》 )。一般狀況下推薦仍是使用gcc的-R或-rpath選項來在編譯時就指定庫的查找路徑,而且該庫的路徑信息保存在可執行文件中,運行時它會直接到該路 徑查找庫,避免了使用LD_LIBRARY_PATH環境變量查找。
(4)交叉編譯時使用軟件的configure參數。例如我編譯minigui-1.3.3,使用以下配置:
#!/bin/bash
rm -f config.cache config.status
./configure --build=i686-linux --host=arm-linux --target=arm-linux /
CFLAGS=-I/usr/local/arm/2.95.3/arm-linux/include /
LDFLAGS=-L/usr/local/arm/2.95.3/arm-linux/lib /
--prefix=/usr/local/arm/2.95.3/arm-linux /
--enable-lite /
--disable-galqvfb /
--disable-qvfbial /
--disable-vbfsupport /
--disable-ttfsupport /
--disable-type1support /
--disable-imegb2312py /
--enable-extfullgif /
--enable-extskin /
--disable-videoqvfb /
--disable-videoecoslcd
這裏我配置了CFLAGS和LDFLAGS參數,這樣一來,我就不用去修改每一個Makefile裏-L和-I參數了,也不用再去配置 LD_LIBRARY_PATH或改寫ld.so.conf文檔了。
Linux下動態庫使用小結
1. 靜態庫和動態庫的基本概念
靜態庫,是在可執行程序鏈接時就已經加入到執行碼中,在物理上成爲執行程序的一部分;使用靜態庫編譯的程序運行時無需該庫文件支持,哪裏均可以用,可是生 成的可執行文件較大。動態庫,是在可執行程序啓動時加載到執行程序中,能夠被多個可執行程序共享使用。使用動態庫編譯生成的程序相對較小,但運行時須要庫 文件支持,若是機器裏沒有這些庫文件就不能運行。
2. 如何使用動態庫
如何程序在鏈接時使用了共享庫,就必須在運行的時候可以找到共享庫的位置。linux的可執行程序在執行的時候默認是先搜索/lib和/usr/lib這 兩個目錄,而後按照/etc/ld.so.conf裏面的配置搜索絕對路徑。同時,Linux也提供了環境變量LD_LIBRARY_PATH供用戶選擇 使用,用戶能夠經過設定它來查找除默認路徑以外的其餘路徑,如查找/work/lib路徑,你能夠在/etc/rc.d/rc.local或其餘系統啓動 後便可執行到的腳本添加以下語句:LD_LIBRARY_PATH =/work/lib:$(LD_LIBRARY_PATH)。而且LD_LIBRARY_PATH路徑優先於系統默認路徑以前查找(詳細參考《使用 LD_LIBRARY_PATH》)。
不過LD_LIBRARY_PATH的設定做用是全局的,過多的使用可能會影響到其餘應用程序的運行,因此多用在調試。(LD_LIBRARY_PATH 的缺陷和使用準則,能夠參考《Why LD_LIBRARY_PATH is bad》)。一般狀況下推薦仍是使用gcc的-R或-rpath選項來在編譯時就指定庫的查找路徑,而且該庫的路徑信息保存在可執行文件中,運行時它會直 接到該路徑查找庫,避免了使用LD_LIBRARY_PATH環境變量查找。
3.庫的連接時路徑和運行時路徑
現代鏈接器在處理動態庫時將連接時路徑(Link-time path)和運行時路徑(Run-time path)分開,用戶能夠經過-L指定鏈接時庫的路徑,經過-R(或-rpath)指定程序運行時庫的路徑,大大提升了庫應用的靈活性。好比咱們作嵌入式 移植時#arm-linux-gcc $(CFLAGS) –o target –L/work/lib/zlib/ -llibz-1.2.3 (work/lib/zlib下是交叉編譯好的zlib庫),將target編譯好後咱們只要把zlib庫拷貝到開發板的系統默認路徑下便可。或者經過- rpath(或-R )、LD_LIBRARY_PATH指定查找路徑。bash