似乎一直沒有靜態編譯Qt的需求:一不在沒有管理員權限的機器上使用,二不製作綠色軟體,三...。動態編譯工作得很好,再配合 nsis 製作一個安裝包,有什麼必要靜態編譯呢?
但論壇中似乎總是不停有人問到靜態編譯的問題,似乎遇到問題的人挺多,用百度或google搜尋"Qt靜態編譯"也能搜到相當多的內容。
正好利用周末時間,自己嘗試編譯一下,順便整理一下,看看到底會發生什麼(儘管以後還是用動態編譯)。
沒特殊說明的話,以下討論的是 MSVC2008 下的情況:
靜態編譯?
或許有兩個層次:
編譯Qt
Qt 預設是動態編譯的,下載Qt的源碼,解壓,而後運行(當系統中有多套編譯環境時,需要通過platform參數指定所用編譯環境 -platform win32-msvc)
configure
然後運行 nmake 就進入漫長的等待了,結束後Qt編譯就完成了。
運行 configure -h 可以得到詳細的協助資訊,包括預設啟用哪些參數等。
* -shared ............ Create and use shared Qt libraries.
-static ............ Create and use static Qt libraries.
如果我們要靜態編譯,只需要在 configure 後添加 -static 就行了。當然根據個人喜好,你可能會添加更多的參數,比如 -no-qt3support 禁用 qt3 支援模組等,不過這與靜態編譯沒有直接關係了。
這樣一來,我們將得到
而不是
去除C、C++運行庫的依賴
通過 configure 的 -static 選項,我們可以編譯出 Qt 的靜態庫,如果只是不想發布程式時發布Qt的動態庫,這個已經完成了。
但是,它們仍依賴 C、C++ 的運行庫。如果還想去除該依賴,需要在靜態編譯Qt之前手動修改
%QTDIR%\mkspecs\win32-msvc2008\qmake.conf
將 QMAKE_CFLAGS_RELEASE 和 QMAKE_CFLAGS_DEBUG 中的 -MD -MDd 分別修改為 -MT 和 -MTd 即可。 這4個參數的含義很容易通過
cl /?
得到
另外,還可以將 CONFIG 中的 embed_manifest_dll embed_manifest_exe 去掉(也可以不去掉)。
注意:對 qmake.conf 的修改最好放在運行 configure 之前,不然的話,修改後還需要手動運行(原因你知道的 )
qmake -r
如何加快編譯
編譯 Qt,應該是一個比較費時費力費空間的(磁碟中沒有15G的空閑空間,都不敢編譯Qt4.7)。編譯時間有選擇地去掉一些東西是比較合適的
外掛程式問題
- 動態編譯時間,外掛程式似乎困擾不少人,經常有人抱怨,程式發布後,jpeg圖片無法顯示?中文顯示亂碼等等?
- 解決方案很簡單,發布時帶上外掛程式就行了(注意路徑)
- 當採用靜態編譯後,外掛程式問題更嚴重了,為什麼呢?外掛程式都成靜態庫了,無法動態載入了(或許已不能被稱為外掛程式了)
常用外掛程式
- 圖片外掛程式 qgif qjpeg qico 等
- 資料庫 qsqlite 等
- 東亞語言 qcncodecs 等
- phonon 後端支援外掛程式
- QStyle 外掛程式
- ...
靜態編譯時間外掛程式的使用(比如,jpeg和gb2312的支援):
#include<QtPlugin>
Q_IMPORT_PLUGIN(qjpeg)
Q_IMPORT_PLUGIN(qcncodecs)
QTPLUGIN += qjpeg qcncodecs
對於Mingw
採用 Mingw 靜態編譯Qt的步驟和上面基本一樣(給configure傳遞 -static參數)。
再就是,修改
%QTDIR%\mkspecs\win32-msvc2005\qmake.conf
為QMAKE_LFLAGS添加 -static 選項
但是 MinGW 編譯的程式會依賴下面的動態庫
- mingwm10.dll
- libgcc_s_dw2-1.dll
對後libgcc這個庫,似乎還好辦,一種說法是修改 <QTDIR>\qmake\Makefile.win32-* 中的
LFLAGS =
為
LFLAGS = -static-libgcc
這個我沒試,Qt4.6.3中 LFLAGS 預設確實為空白,但Qt4.7中預設已經添加了該選項
對與 mingwm10 這個動態庫,似乎比較難辦。因為它似乎和
有關。