Qt靜態編譯 動態鏈結庫搜尋路徑

2021-09-11 07:27:01 字數 2267 閱讀 7590

陌 上 花 開

由乙個問題引出靜態編譯qt的必要: 如何在乙個系統中編譯得到乙個qt可執行程式,然後,可以拿到另乙個沒有安裝qt的系統(同型號)中可以直接執行?

一般情況下,我們用qt編譯出來的程式是要依賴於系統qt庫的,也就是這個程式移到別的沒有安裝qt庫的系統上是不能使用的。會提示缺少xx庫檔案之類的錯誤, 這是動態編譯的結果, 即在編譯你的qt**時使用的是動態編譯方式。   若要想靜態編譯,則需要安裝靜態編譯的qt,可以參考:

將qt11安裝在目錄/opt/qt5.11.1/, 自己在qt creator下編譯的程式可以正常執行。然後,手動改安裝目錄的名字,將qt5.11.1資料夾名字改為qt5.11.1c,然後,之前可以執行的qt程式不能執行了,報錯:

原因分析:

編譯程式時,採用的動態編譯,而且,qmake生成的makefile檔案中使用了g++ rpath選項來指定執行時的搜尋路徑為/opt/qt5.11.1/5.11.1/gcc_64/lib,程式執行時需要載入動態鏈結庫,會首先從g++ rpath指定的這個路徑去搜尋,但是該了名字之後該路徑不存在了,於是從系統預設的動態鏈結庫目錄(例如/usr/lib)中去搜尋,結果從/usr/lib/x86_64-linux-gnu/目錄中搜尋到了,例如libqt5widgets.so.5,但是這個鏈結庫對應的是低版本的qt庫(可能系統自帶的或以前在系統中安裝過)(參考本文後半ldd部分),於是提示了上述的錯誤!

關於linux搜尋動態鏈結庫的方法,可以參考我的:

####################

使用ldd命令可以檢視可執行檔案依賴那些動態連線庫:

正常時會顯示:

在 ldd 命令列印的結果中,「=>」左邊的表示該程式需要連線的動態連線庫的名稱(這些庫的名字資訊應該是編譯程式的時候儲存到可執行檔案裡面的),右邊表示由 linux 找到的對應的庫檔案在檔案系統中的具體位置。

ld-linux.so

是專門負責尋找庫檔案的庫。以

cat為例,

cat首先告訴

ld-linux.so

它需要libc.so.6

這個庫檔案,

ld-linux.so

將按一定順序找到

libc.so.6

庫再給cat

呼叫。那

ld-linux.so

又是怎麼找到的呢?其實不用找,

ld-linux.so

的位置是寫死在程式中的,

gcc在編譯程式時就寫死在裡面了。

gcc寫到程式中

ld-linux.so

的位置是可以改變的,通過修改

gcc的

spec

檔案。上面出錯的資訊是為什麼?經檢視,在系統的usr/lib/x86_64-linux-gnu/目錄下存在對應的qt的動態鏈結庫檔案(可能系統自帶的或以前在系統中安裝過),這個目錄下的動態鏈結庫檔案與qt安裝目錄下的動態鏈結庫檔案有什麼區別?:

以libqt5core.so.5檔案為例子,在qt的安裝目錄下/opt/qt5.11.1/5.11.1/gcc_64/lib中:

可知,其為乙個鏈結檔案。

在usr/lib/x86_64-linux-gnu/目錄下:

可知,在兩個目錄下libqt5core.so.5都是乙個鏈結,只是指向的檔案不同,  usr/lib/x86_64-linux-gnu/中的鏈結指向了qt5.2版本,可能之前安裝過qt5.2,或者系統自帶,所以出錯。

另外,更改了

qt的安裝目錄檔名後,更新

/etc/ld.so.conf.d/

,在這個目錄下增加乙個

conf

檔案,包含新的路徑就可以找到

qt的庫了,即告訴系統乙個新的動態鏈結庫搜尋路徑。

linux 編譯靜態鏈結庫和動態鏈結庫

我們通常把一些公用函式製作成函式庫,供其它程式使用。函式庫分為靜態庫和動態庫兩種。靜態庫在程式編譯時會被連線到目標 中,程式執行時將不再需要該靜態庫。動態庫在程式編譯時並不會被連線到目標 中,而是在程式執行是才被載入,因此在程式執行時還需要動態庫存在。本文主要通過舉例來說明在linux中如何建立靜態...

動態鏈結庫 靜態鏈結庫

包含標頭檔案和庫 idir 指定編譯查詢標頭檔案的目錄,常用於查詢第三方的庫的標頭檔案,例 gcc test.c i.inc o test。ldir 指定鏈結時查詢lib的目錄,常用於查詢第三方庫。llibrary 指定額外鏈結的lib庫 巨集定義 dmacro 以字串 1 預設值 定義 macro...

靜態鏈結庫 動態鏈結庫

庫是寫好的現有的,成熟的,可以復用的 現實中每個程式都要依賴很多基礎的底層庫,不可能每個人的 都從零開始,因此庫的存在意義非同尋常。本質上來說庫是一種可執行 的二進位制形式,可以被作業系統載入記憶體執行。庫有兩種 靜態庫 a lib 和動態庫 so dll windows上對應的是.lib dll ...