Linux下快速靜態編譯Qt以及Qt動態/靜態版本共存
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
問題解決!
相關文章
- Qt for Windows:Qt 5.8.0 MinGW 靜態編譯版本(包含OpenSSL)QTWindows編譯
- 靜態編譯Qt5.4.1和Qt WebKit編譯QTWebKit
- apache動態編譯/靜態編譯區別Apache編譯
- linux下靜態庫、動態庫編譯及makefile書寫Linux編譯
- windows下使用mingw和msvc靜態編譯Qt5.15.xxWindows編譯QT
- VS2010 編譯QT 4.7.3 靜態庫(lib)編譯QT
- Linux 依賴動態庫 / 靜態庫的動態態庫 / 靜態庫Linux
- linux成長之路(gcc編譯器、靜態庫、動態庫)LinuxGC編譯
- Linux下建立靜態庫、動態庫以及簡單的makefileLinux
- 有關Linux的可執行程式——動態編譯、靜態編譯、readelfLinux行程編譯
- linux下的靜態庫與動態庫Linux
- Android NDK祕籍--編譯靜態庫、呼叫靜態庫Android編譯
- QT之靜態函式傳送訊號QT函式
- HTML也可以靜態編譯?HTML編譯
- 偽靜態、靜態和動態的區別
- Linux下把靜態庫編譯進PHP的方法Linux編譯PHP
- Linux下的靜態庫、動態庫和動態載入庫Linux
- 簡述Linux下的靜態庫和動態庫Linux
- Linux下的靜態連結與動態連結Linux
- Linux下的共享庫(動態庫)和靜態庫Linux
- Linux環境下建立靜態庫和動態庫Linux
- Arm64架構下靜態編譯Nginx架構編譯Nginx
- [譯] 用 Workers 讓靜態網站動態化網站
- JIT-動態編譯與AOT-靜態編譯:java/ java/ JavaScript/Dart亂談編譯JavaScriptDart
- WPF:靜態、動態資源以及資源詞典
- 動靜態庫
- 靜態代理和動態代理
- 靜態路由和動態路由路由
- oracle 監聽 靜態 動態Oracle
- 靜態庫與動態庫
- go編譯靜態檔案到exeGo編譯
- Android:JNI與NDK(二)交叉編譯與動態庫,靜態庫Android編譯
- C/C++ 編譯器和偵錯程式以及靜態庫、動態庫使用匯總(轉)C++編譯
- .NET偽靜態使用以及和純靜態的區別
- 靜態變數與靜態方法變數
- Linux下靜態庫生成指南Linux
- DEDE整站動態/靜態轉換
- ios靜態庫和動態庫iOS