1. 編譯程式時用到動態庫,該從那些地方查詢,按照怎麼樣的順序查詢?
2. 執行程式時需要動態庫,該從那些地方查詢,按照怎麼樣的順序查詢?
1. gcc 編譯時引數-l指定的路徑
2. 環境變數 library_path
3. 系統預設庫位置 /lib /usr/lib
1. gcc 編譯時指定的執行時庫路徑 -wl,-rpath
2. 環境變數 ld_library_path
3. ldconfig 快取 /etc/ld.so.cache
4 系統預設庫位置 /lib /usr/lib
library_path和ld_library_path是linux下的兩個環境變數,二者的含義和作用分別如下:
library_path環境變數用於在程式編譯期間
export library_path=libdir1:libdir2:$library_path
ld_library_path環境變數用於在程式載入執行期間查詢動態鏈結庫時指定除了系統預設路徑之外的其他路徑,注意,ld_library_path中指定的路徑會在系統預設路徑之前進行查詢。設定方法如下(其中,libdir1和libdir2為兩個庫目錄):
export ld_library_path=libdir1:libdir2:$ld_library_path
舉個例子,我們開發乙個程式,經常會需要使用某個或某些動態鏈結庫,為了保證程式的可移植性,可以先將這些編譯好的動態鏈結庫放在自己指定的目錄下,然後按照上述方式將這些目錄加入到ld_library_path環境變數中,這樣自己的程式就可以動態鏈結後載入庫檔案執行了。
區別與使用:
開發時,設定library_path,以便gcc能夠找到編譯時需要的動態鏈結庫。
發布時,設定ld_library_path,以便程式載入執行時能夠自動找到需要的動態鏈結庫。
注意:新設定變數ld_library_path,下次開機,一切設定將不復存在;如何把這個值持續寫到 ld_library_path 裡呢?
我們就會想有不有什麼一勞永逸地方法,使得設定之後就不用再去設定了?答案是肯定的。有兩種:
1、在~/目錄下開啟.bash_profile檔案,設定環境變數如下:
ld_library_path=dir:$ld_library_path
export ld_library_path
2、在linux下,還 提供了另外一種方式來完成同樣的功能,你可以把這些目錄加到/etc/ld.so.conf中,然後呼叫ldconfig。
-i,新增包含路徑
-i 在編譯時用,告訴編譯器去哪個路徑下找檔案
如:-i /home/hello/include
表示將/home/hello/include目錄作為第乙個尋找標頭檔案的目錄。
編譯器的尋找順序是:/home/hello/include-->/usr/include-->/usr/local/include。如果在/home/hello/include中有個檔案hello.h,則在程式中用#include就能引用到這個檔案。
可以加多個包含路徑,編譯器的尋找順序為新增的順序。
-l,新增引用鏈結庫
告訴鏈結器(linker),程式需要鏈結pthread這個庫,這裡的pthread是庫名不是檔名,具體來說檔案句是libpthread.so。
-l,新增鏈結庫路徑
-l 後跟路徑,告訴鏈結器從哪找庫(.so檔案),只有在鏈結時會用到。
如:-l /home/hello/lib
表示將/home/hello/lib目錄作為第乙個尋找庫檔案的目錄,尋找順序是:/home/hello/lib-->/usr/lib-->/usr/local/lib。
可以加多個包含路徑,鏈結器的尋找順序為新增的順序。
-wl:rpath,新增執行時庫路徑
-wl:rpath 後面也是路徑,執行的時候用。這條編譯指令會在編譯時記錄到target檔案中,所以編譯之後的target檔案在執行時會按這裡給出的路徑去找庫檔案。
如:-wl:rpath=/home/hello/lib
表示將/home/hello/lib目錄作為程式執行時第乙個尋找庫檔案的目錄,程式尋找順序是:/home/hello/lib-->/usr/lib-->/usr/local/lib。
可以加多個包含路徑,程式在執行時的尋找順序為新增的順序。
參考:
linux 動態鏈結庫載入
linux 動態鏈結 linux 中的應用程式以以下兩種方式之一鏈結到外部函式 要麼在構建時與靜態庫 lib a 靜態地鏈結,並且將庫 包含在該應用程式的可執行檔案裡 要麼在執行時與共享庫 lib so 動態地鏈結。通過動態鏈結裝入器,將動態庫對映進應用程式的可執行記憶體中。在啟動應用程式之前,動態...
動態鏈結庫延遲載入
開發的時候遇到乙個問題,有乙個可執行程式需要依賴另外乙個目錄的動態庫,但是對這個dll介面的引用採用的是靜態依賴的方式。解決不難,可以通過loadlibrary動態載入,然後呼叫其介面。但是這用就沒法方便的通過靜態以依賴的方式方便的呼叫其介面了。探索後發現vs支援延遲繫結。就是呼叫的時候可以通過靜態...
手動載入動態鏈結庫
手動載入動態鏈結庫常用於外掛程式式架構開發 dlfcn.h標頭檔案提供了api 以下我們給出常用的4個函式 open the shared object file and map it in return a handle that can be passed to dlsym to get sym...