上頭需要把專案從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...