Linux動態庫的查詢路徑

2021-09-12 22:21:32 字數 2069 閱讀 1669

上頭需要把專案從windows系統移動到linux下,作為對linux半吊子的我卻無意承擔了這個工作,從此填坑深如海。原專案實在msvc+qt開發的,還好qt是跨平台的,但是windows和linux的執行還是有所差距的。以下記錄linux下動態庫的搜尋路徑,多數內容來自csdn中的其他大神。

這個過程是由ld程式來執行的,所以編譯時找不到動態庫的位置的話,經常就會看到這種錯誤:

這個過程嚴格意義上來說並不能說是鏈結,因為在這裡ld-linux程式並沒有真正的把庫裡面的函式的執行**寫到可執行檔案裡面,只是把一些符號還有其他的必要資訊寫道了可執行檔案裡面,供可執行檔案執行時查詢。

總的來說,ld-linux程式在這一步裡面就是做了兩個事情:

1.查詢動態庫中是否含有我們需要的符號(函式和全域性變數),如果都能找到,則鏈結允許通過,生成了可執行檔案。

2. 在可執行檔案中寫入了符號和其他必要的資訊(例如符號的位址),供可執行檔案執行時查詢。

(1)ld-linux.so.6由gcc的spec檔案中所設定

(2)gcc --print-search-dirs所列印出的路徑,主要是libgcc_s.so等庫。可以通過gcc_exec_prefix來設定

(3)library_path環境變數中所設定的路徑,或編譯的命令列中指定的-l/usr/local/lib

(4)binutils中的ld所設定的預設搜尋路徑順序,編譯binutils時指定。(可以通過「ld --verbose | grep search」來檢視)

(5)二進位制程式的搜尋路徑順序為path環境變數中所設定。一般/usr/local/bin高於/usr/bin

(6)編譯時的標頭檔案的搜尋路徑順序,與library的查詢順序類似。一般/usr/local/include高於/usr/include

(1)ld-linux.so.6在可執行的目標檔案中被指定,可用readelf命令檢視

(2)ld-linux.so.6預設在/usr/lib和lib中搜尋;當glibc安裝到/usr/local下時,它查詢/usr/local/lib

(3)ld_library_path環境變數中所設定的路徑 ,使用qt時qtcreator會自動根據專案pro檔案中的配置將所需的動態庫路徑加入該環境變數,但這只在qtcreator中可見,即實際環境中並不存在該路徑。在具體見

(4)/etc/ld.so.conf.d/libc.config(或/usr/local/etc/ld.so.conf)中所指定的路徑,並由ldconfig命令生成二進位制的ld.so.cache以更新配置

(1)在qtcreator的pro配置檔案中不可顯示將/usr/include作為所需庫標頭檔案的包含路徑和依賴路徑。如下圖所示,這將導致一系列問題。如

(2)windows下的動態庫匯出匯入說明為__declspec(dllexport) _ _ declspec(dllimport)

而類似的,在linux下可以使用__attribute__((visibility(「default」)))標籤和__attribute__ ((visibility(「hidden」)))標籤來控制函式或者類在生成的動態庫中可見或者不可見,可以理解為匯出或者不匯出。在編譯時設定 -fvisibility=hidden,則不加 visibility宣告的都預設為hidden; gcc預設設定 -fvisibility=default,即全部可見。

(3)在linux下的qtcreator中編譯時為預設-fvisibility=default,即全部都可見。可通過在配置檔案中設定qmake_cxxflags += -fvisibility=hidden 來更改預設。

參考文獻:

linux動態庫的查詢路徑

linux動態庫的匯出控制

Linux動態庫的查詢路徑

前兩天寫了乙個動態庫,然後試圖編譯到程式裡面去執行,結果發現編譯的時候通過gcc的 l引數來指定路徑僅僅能讓編譯通過,執行時還是會出問題的。比如下面這個例子 main.c是主程式,sum.c中間含有乙個函式add,用來執行加法,如下 1 2 main.c3 4 include 5 6int add ...

Linux動態庫的查詢路徑

前兩天寫了乙個動態庫,然後試圖編譯到程式裡面去執行,結果發現編譯的時候通過gcc的 l引數來指定路徑僅僅能讓編譯通過,執行時還是會出問題的。比如下面這個例子 main.c是主程式,sum.c中間含有乙個函式add,用來執行加法,如下 1 2 main.c3 4 include 5 6int add ...

GNU GCC查詢路徑

1.標頭檔案 gcc 在編譯時如何去尋找所需要的標頭檔案 header file的搜尋會從 i開始 然後找gcc的環境變數 c include path,cplus include path,objc include path 再找內定目錄 usr include usr local include...