Linux 靜態庫與動態庫搜尋路徑設定

2021-06-20 18:48:37 字數 4719 閱讀 1163

分類: my study record

2011-01-12 17:13

8977人閱讀收藏

舉報 linux

library

path

文件gtk

makefile

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下的,也是不會被使用的,結果編譯過程中抱錯,缺少***庫,去檢視發現明明就在那放著,搞的想大罵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指定查詢路徑。

Linux 靜態庫與動態庫搜尋路徑設定

1.連線和執行時庫檔案搜尋路徑到設定 庫檔案在連線 靜態庫和共享庫 和執行 僅限於使用共享庫的程式 時被使用,其搜尋路徑是在系統中進行設定的。一般 linux 系統把 lib 和 usr lib 兩個目錄作為預設的庫搜尋路徑,所以使用這兩個目錄中的庫時不需要進行設定搜尋路徑即可直接使用。對於處於預設...

Linux靜態庫與動態庫

靜態庫 a 靜態庫的 在編譯過程中已經被載入可執行程式,因此體積較大。編譯程式時候需要庫作依賴,執行時候不需要。方便,不再需要外部函式庫支援 缺點 1 因為靜態庫被鏈結後直接嵌入可執行程式中,相當於每乙個可執行程式裡都有乙個庫的副本,浪費空間 2 一旦庫中有bug,需要重新編譯。建立步驟 1 編寫函...

linux動態庫與靜態庫

現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的 都從零開始。盡量不重複做別人已經做過的事,站在巨人的肩膀上 做事情。根據鏈結時期的不同,庫又有 靜態庫和共享庫 動態庫 二者的不同點在於 被載入的時刻不同,靜態庫的 在編譯過程中已經被載入可執行程式,因此體積較大。共享庫的 是在可執行程式執行時...