Linux下快速靜態編譯Qt以及Qt動態/靜態版本共存

weixin_33806914發表於2018-03-11

Qt下靜態編譯Qt,根據我的經驗,如果按照Windows下那種直接拿官方sdk安裝之後的檔案來編譯是行不通的,需要直接下載Qt的source包,目前諾基亞的原始碼叫做qt-everywhere-opensource-src的tar包,到網上一查,乖乖,大部分人編譯這個包居然花費了12~13個小時!但是,根據我在Windows下靜態編譯Qt的經驗,其實這之中很多東西都是可以不用編譯的,最終我大約用了40分鐘編譯完成了全部內容。如果你直接使用官方的sdk安裝,那麼你就已經有了一個動態庫,現在你又通過原始碼包編譯,那麼只要編譯出靜態庫,因為你已經有動態庫,你甚至只需要編譯靜態release庫就足夠了,誰會在平時編譯的時候就要用那種浪費時間的靜態編譯?等到產品要部署到別的機器的時候,Qt需要用的時候連線上就可以了,這樣其它的內容,如動態庫的demo,examples都依舊可用,安裝兩個版本又不會花太多時間,豈不兩全其美?長話短說,現在說安裝步驟。

 

1. 到網上下載qt-everywhere原始碼包,

 

如果你只要庫,那麼你也可以到下面的網址找到你需要的版本。

 

http://www.qtcn.org/bbs/read.php?tid=1075

 

2. 解壓縮到你的目標目錄

 

3. 通過configure選擇要編譯的部分。

 

   你可以通過直接修改configure檔案中的QT_DEFAULT_BUILD_PARTS="libs tools examples demos docs translations",把examples,docs,demos都去掉(我只去掉了這三個,理論上如果安裝了動態版本,tools和translations(這個是linguist要用的)也是可以去掉的。你也可以通過在最終的configure指令中加入 –no-make ***(這裡就是剛才提到的PARTS名字),而無需修改configure檔案

 

  還有一些選項是預設的,你也可以指定選項。這些預設選項在大部分情況下都是沒問題的,可是如果你的程式要部署到某些不確定的linux系統上,譬如有的系統連jpg,png的庫都沒有(這些在configure預設選項中使用的是系統庫,如果系統沒有這些庫,豈不悲劇),那麼你可以加入 –qt-gif  -qt-libpng –qt-libmng –qt-libjpeg幾個選項。

 

  如果你決定只用靜態庫來做最終產品釋出,那麼你沒有必要編譯debug庫,只需要編譯release即可。

 

4. 使用configure生成makefile

 

  因為你不但想用自己編譯的靜態庫,你還想能夠用sdk自動安裝的動態庫以及那些demos,examples,為了能讓兩個Qt庫共存,configure時必須為靜態庫制定一個與動態庫所在位置不同的資料夾,例如我的sdk安裝到 /opt/qtsdk-2010.05/下,那麼我就在/opt下建立了一個叫qtstatic的資料夾來存放靜態庫,然後使用的configure命令:

 

./configure –prefix /opt/qtstatic –static –release。當然,我不喜歡看到滿屏亂七八糟的輸出,以及因為一個小錯誤突然終止了編譯,所以又指定了以下選項:

 

-continue  當發生錯誤時,儘可能繼續編譯

 

-silent 進行make時只會顯示警告和錯誤等,不會把編譯指令也輸出到螢幕上

 

當然,如果你最初沒有通過修改configure檔案的方式來刪減編譯模組,不要忘記加上-nomake選項,譬如你不想編譯examples,就可以加上:

 

-nomake examples  ,依次類推

 

因為工程比較大,所以這個步驟可能會花費幾分鐘的時間。如果你指定編譯的內容不是很多,應該可以很快完成。

 

5. 編譯和安裝

 

  最後當然就是make和make install了,不過不要忘了make還有多執行緒編譯的功能喲!如果你的機器這段時間不打算做別的事情的話,完全可以加入以下選項:

 

-k  當發生錯誤時,儘可能繼續編譯

 

-j N  同時進行N項編譯,建議N的值為你的CPU核數X1.5。當然,我選的值略微狠了點,我的電腦是奔騰雙核T4300,make指令為: make –k –j 4    ,然後我就看到系統監視器裡CPU直接飆到100%了。

 

編譯完成,make install就可以。當然,作為linux系統,需要注意資料夾的許可權問題……呃,如果你不瞭解這個問題,我想你需要在linux上多下點兒功夫

 

6. 如何靜態編譯一個程式

 

  在pro檔案中,加入 

 

  CONFIG +=static或者

 

  CONFIG +=staticlib,這個具體取決於你的工程型別了。

 

  這樣Qt就會讓編譯器儘量尋找靜態庫來連線(包括Qt庫之外的那些庫),當然,這不排除Qt會靜態連線一些會導致相容性問題的庫。這個在Qt Centre中有人提出了一個解法,如有需要可以查閱:

 

http://www.qtcentre.org/wiki/index.php?title=Building_static_applications

 

7. 動態/靜態兩個版本共存問題

 

  通常,你是不需要在系統變數中加入Qt庫的位置的。Qt Creator可以自動掃描到系統中存在的Qt庫版本,如果掃描不到,你可以通過Creator的 Tool->Options->Qt4中新增靜態庫的路徑。而QDevelop雖然沒有那麼智慧,你也可以手動指定INCLUDE和LIB的位置。或許,這根本就不是一個問題。如果你懷念動態庫,或者在產品釋出之前並不想體驗靜態編譯那種蝸牛爬一般的速度,你可以在pro檔案中指定CONFIG += shared,而且,要記得在Project中選擇相應的版本。

 

8. 靜態版本過大的問題

 

  首先,靜態編譯的Qt程式一個debug版程式150M左右,一個release版本10M左右,這樣你知道為什麼我不會編譯靜態debug庫了吧?因為沒有必要。你可以使用strip,UPX(Windows)等工具來壓縮你生成的龐大程式。空間與速度從來都是一對冤家,Windows下靜態編譯出的程式,經過UPX壓縮可以減少到原來的一般體積,但是啟動速度也隨之嚴重下降。當然,論程式啟動速度,自己的設計和實現才是關鍵所在,最後釋出的程式要不要壓縮,那需要根據實際情況而定。

 

  

 

祝你與Qt相處愉快!

 

PS. configure階段出現 “Basic XLib functionality test failed“的解決辦法:

 

編譯qt-x11-opensource-src-4.5.3是出現“Basic XLib functionality test failed“

解決方法:

 

此完整出錯資訊是在./configure階段
Basic XLib functionality test failed!
You might need to modify the include and library search paths by editing
QMAKE_INCDIR_X11 and QMAKE_LIBDIR_X11 in /home/zhu/Qt/qt-x11-opensource-src-4.5.2/mkspecs/linux-g++

 

config.test/x11/xlib 執行make命令,看出錯資訊
g++ -Wl,-O1 -o xlib xlib.o    -L/usr/X11R6/lib -lXext -lX11 -lm
/usr/bin/ld: cannot find -lXext
可以看到,g++在/usr/X11R6/lib下,找不到libXext.so

 

其原因就在於需要安裝libX11的開發包,根據自己的系統特點,安裝 libX11-dev libXext-dev libXtst-dev

 

對於Ubuntu,直接 sudo apt-get install libx11-dev libxext-dev libxtst-dev

問題解決!

相關文章