在去年4月份的時候,我寫過一篇動態編譯Qt5.6.0的文章,當時是為了解決webkit不能在winxp下面跑的問題,動態編譯有一個缺點,就是發布的時候,要攜帶一大堆dll,使安裝包的體積增大。而靜態編譯能夠解決這個問題,但是靜態編譯也有缺點,那就是編譯時間很長,而且每次不管哪個模塊有改動,就必須重新編譯鏈接整個項目。現在Qt最新版本已經到5.8.0RC了,但5.6.2應該是最后一個支持xp的版本了,5.7.0源碼里configure已經去掉了-target xp這個選項。
注意:閉源項目鏈接靜態Qt庫並發布軟件是違反LGPL協議的,請遵守此協議,否則因此造成的任何后果,與本文作者無關。
一、准備
需要的工具和上篇文章里面列出來的差不多,除了下面幾個
1、qt-everywhere-opensource-src-5.6.2源碼
2、Precompiled ICU已經靜態編譯好的icu,注意下載vs2013版本的,我下載的是icu-58.2-vs2013.7z
3、win_flex_bison,編譯webkit需要
二、獲取webkit源碼
先解壓5.6.2的源碼到C:\Qt\qt-everywhere-opensource-src-5.6.2,打開CMD轉到此目錄,輸入Git clone git://code.qt.io/qt/qtwebkit.git下載源碼,由於是國外地址,請留意上篇文章的提示。下載完成之后,再執行:git checkout 5.6.2,注意checkout這一步是必須的,每個Qt版本都有對應的webkit版本,不執行這一步下載的webkit源碼應該是當前的最新版本5.8.0RC對應的源碼,編譯很可能會出問題。
三、編譯openssl
編譯過程和上篇文章大致相同,不過靜態編譯的時候要用ms/nt.mak,而不是ms/ntdll.mak,另外安裝目錄(-prefix),我這里是:C:\Qt\openssl-static,其他操作參考上篇文章即可。
四、編譯Qt5.6.2
打開VS2013的x86命令提示工具,執行以下命令(確保Python,ruby,perl,jom已經添加到了PATH):
- SET ICU_DATA=C:\Qt\icu-58.2-vs2013\data
- SET PATH=C:\Qt\icu-58.2-vs2013\bin;C:\Qt\icu-58.2-vs2013\lib;C:\Qt\win_flex_bison-latest;C:\Qt\qt-everywhere-opensource-src-5.6.2\qtbase\bin;C:\Qt\qt-everywhere-opensource-src-5.6.2\gnuwin32\bin;%PATH%
然后創建C:\Qt\build-Qt5.6.2-msvc2013-static-x86-debug和C:\Qt\build-Qt5.6.2-msvc2013-static-x86-release兩個目錄,用於分別編譯debug和release兩個版本,再創建C:\Qt\Qt5.6.2-msvc2013-static-x86目錄,作為Qt的安裝目錄
修改C:\Qt\qt-everywhere-opensource-src-5.6.0\qtbase\mkspecs\common\msvc-desktop.conf的74行和75行為:/SUBSYSTEM:CONSOLE\",5.01\" 和 /SUBSYSTEM:WINDOWS\",5.01\"
修改C:\Qt\qt-everywhere-opensource-src-5.6.2\qtwebkit\Source\WebCore\platform\qt\QtTestSupport.h的28行和30行:
- #if defined(BUILDING_WEBKIT)
- #define TESTSUPPORT_EXPORT //Q_DECL_EXPORT
- #else
- #define TESTSUPPORT_EXPORT //Q_DECL_IMPORT
- #endif
把Q_DECL_EXPORT和Q_DECL_IMPORT注釋掉,這個是導出DLL用的,靜態編譯沒有這個東西。
注意:編譯webkit只能用VS2013,否則webkit不會被編譯:參考C:\Qt\qt-everywhere-opensource-src-5.6.2\qtwebkit\Tools\qmake\mkspecs\features\configure.prf文件第132行:
如果你的編譯器不是VS2013,webkit構建的時候會自動跳過。。這也是一個坑,筆者之前用VS2015去編譯,就發現了這個問題。
編譯debug版本
轉到C:\Qt\build-Qt5.6.2-msvc2013-static-x86-debug
執行:"../qt-everywhere-opensource-src-5.6.2/configure.bat" -prefix C:/Qt/Qt5.6.2-msvc2013-static-x86 -debug -platform win32-msvc2013 -opensource -static -static-runtime -nomake examples -nomake tests -skip qtwebengine -skip qtwebview -accessibility -plugin-sql-odbc -plugin-sql-sqlite -opengl desktop -target xp -largefile -qt-zlib -qt-pcre -icu -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -rtti -ssl -openssl-linked -mp -I C:\Qt\openssl-static\include -I C:\Qt\icu-58.2-vs2013\include -L C:\Qt\openssl-static\lib -L C:\Qt\icu-58.2-vs2013\lib -l gdi32 -D _USING_V110_SDK71_ -D U_STATIC_IMPLEMENTATION
輸入y接受協議,等待配置完成
執行:jom或者nmake
編譯完成后,如果沒有出現錯誤,執行,nmake install
編譯release版本
轉到 C:\Qt\build-Qt5.6.2-msvc2013-static-x86-release
執行:"../qt-everywhere-opensource-src-5.6.2/configure.bat" -prefix C:/Qt/Qt5.6.2-msvc2013-static-x86 -release -platform win32-msvc2013 -opensource -static -static-runtime -ltcg -nomake examples -nomake tests -skip qtwebengine -skip qtwebview -accessibility -plugin-sql-odbc -plugin-sql-sqlite -opengl desktop -target xp -largefile -qt-zlib -qt-pcre -icu -qt-libpng -qt-libjpeg -qt-freetype -qt-harfbuzz -rtti -ssl -openssl-linked -mp -I C:\Qt\openssl-static\include -I C:\Qt\icu-58.2-vs2013\include -L C:\Qt\openssl-static\lib -L C:\Qt\icu-58.2-vs2013\lib -l gdi32 -D _USING_V110_SDK71_ -D U_STATIC_IMPLEMENTATION
輸入y接受協議,等待配置完成
執行:jom或者nmake
編譯完成后,如果沒有出現錯誤,執行,nmake install
注意:
1、configure.bat執行之后,可能會出現一堆警告:
C:\Qt\build-Qt5.6.2-msvc2013-static-x86-debug/qtbase/mkspecs/qconfig.pri:22: Extra characters after test expression.
...
原因是Qt的構建腳本有問題,編輯C:\Qt\build-Qt5.6.2-msvc2013-static-x86-debug/qtbase/mkspecs/qconfig.pri
Qt的構建腳本,在獲取cl編譯器的版本號時,字符串截取有問題,手動編輯一下,改成下面這樣即可:
2、nmake install之后,C:\Qt\build-Qt5.6.2-msvc2013-static-x86-debug和C:\Qt\build-Qt5.6.2-msvc2013-static-x86-release兩個構建目錄不能刪除
因為之后編譯項目的時候,會鏈接到一些lib,比如webkit1.lib,這些lib,install的時候並沒有安裝到C:\Qt\Qt5.6.2-msvc2013-static-x86\lib
看到這里有人肯定會問為什么不一起編譯debug和release,其實是可以的,直接把release版本的configure命令-release改為-debug-and-release即可。
五、測試運行
用QtCreator新建一個項目,創建一個QWebView,然后加載http://www.baidu.com/
- CONFIG(release, debug|release): QMAKE_LFLAGS += /LTCG
- QMAKE_LFLAGS += /IGNORE:4099
- QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:CONSOLE\",5.01\"
- QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS\",5.01\"
- DEFINES += _USING_V110_SDK71_
- DEFINES += U_STATIC_IMPLEMENTATION
注意在pro里面增加上面的代碼,/IGNORE:4099表示忽略沒有找到pdb的警告,因為這個預編譯好的icu是沒有自帶pdb的,如果不加這一項,編譯的時候會出現很多沒有找到pdb的警告。我們通常也不會去調試icu的代碼,所以忽略這個警告對我們沒有什么影響。
U_STATIC_IMPLEMENTATION這個宏是靜態鏈接icu要使用的,請參考icu的幫助文檔
項目構建之后,生成的exe有54M!下圖是運行結果,筆者在xp系統上也測試過,能正常運行。
http://blog.csdn.net/kenier/article/details/54598698