靜態編譯Qt5.4.1和Qt WebKit

網事已瘋發表於2015-03-25

blog文章地址:http://godebug.org/index.php/archives/133/

WebKit是個好東西,做爬蟲、顯示網頁還是想用HTML來做桌面應用的介面都可以用他,不過一直以來都覺得自己編譯webkit費力不討好,所以都是用的qt官方編譯好的,至於靜態編譯webkit,我之前一直以為是根本不可能的。後來看qt forum上說其實是可以的,不過是因為開源協議的問題qt預設的靜態編譯只是把webkit給排除了,自己編譯一下webkit就好了,既然如此,那我就當小白試一下。不過最後發現靜態編譯webkit其實也不難,就是比較麻煩,佔用了幾十個G的硬碟歷時一天終於把這玩意編譯完了。所以簡單記一下編譯的流程,方便大家。不過得提醒大家閉源專案靜態連結qt和webkit是違反LGPL協議的,除非你把你的程式以GPL協議開源,要不就是違法的。

首先是亂七八糟的工具的安裝
1.Python,我機器上本來就用py 2.7和3.3,不過編譯的時候用的是2.7
2.Ruby,我裝的是 2.2.1,官網上說需要ruby,不過編譯的過程中我沒發現有什麼地方用到這玩意,而且在windows上裝個ruby也不是太有用,各位可以先不裝他,等編譯的時候遇到問題再裝也不遲,我就不去試到底需不需要了.....
3.Perl,webkit和OpenSSL的編譯指令碼就是perl寫的,這個是鐵定要用了
4.OpenGL ES SDK,我也不知道為什麼要用到這玩意,我明明選的是-opengl desktop,估計是qt的一個bug
4.一個編譯器,看你自己想用什麼了,我用的是vs2013

這些都裝好了之後就是加兩個第三方的庫,icu和OpenSSL,icu是編譯webkit所必須的,OpenSSL不是必須的,前提是你不打算用webkit訪問https的網站...
我一開始嘗試自己編譯icu,這貨倒也不是太難編譯,不過就是編譯選項中沒有任何方法能改成使用靜態執行時的,要自己改config和makefile檔案,我懶得動彈,就找了個現成的編譯好的Precompiled ICU,不過用這裡的icu有個問題,就是它提供的靜態編譯的icu庫木有pdb除錯資訊,在連結的時候會有一堆LNK4099的warning,這傻逼warning雖然可以確定是完全人畜無害的(我們幾乎沒可能去除錯icu裡面的程式碼),但是因為VS有個操蛋的bug,這個wrning是無法遮蔽的,而因為QtCore也用到了icu,於是你每個qt專案都會看到一堆LNK4099的warning.....每次編譯的時候...WTF...如果不想看到,就自己編譯icu吧,這個連結也給了讓icu靜態連結執行時的patch,自己動手豐衣足食。
編譯 OpenSSL我就不多說了,比較簡單,我之前也寫過http://www.godebug.org/index.php/archives/104/

都搞定之後,開始編譯Qt,直接下載zip格式的原始碼,不要用tar的,裡面缺少configure.exe,那是給linux用的,解壓,我放在F:\qt-everywhere-opensource-src-5.4.1\,然後是修改mkspace中的配置檔案,因為Qt也沒有能從命令列修改為使用靜態執行時的選項,找到qtbase\mkspace\編譯器名\qmake.conf,編輯,把裡面的兩個MD都改成MT,一個MDd改成MTd就可以了,我這裡用的是VS,gcc的話應該是把QMAKE_CXXFLAGS一項中加個-static,儲存就可以了。
然後是設定環境變數,這裡我建議直接遮蔽系統的環境變數,全部都重新設定,因為系統裝安裝的亂七八糟工具都有可能影響編譯,比如說裝了msysgit什麼的,裡面的perl.exe就會有影響。開個命令提示符CD到原始碼的根目錄,

set PATH=C:\Windows;C:\Windows\System32;D:\Ruby22-x64\bin;C:\Python27;C:\Python27\Scripts;F:\icu\lib;F:\icu\bin;F:\gles_sdk\x86;D:\Perl64\bin;F:\openssl\bin;
set INCLUDE=F:\icu\include;F:\gles_sdk\include;F:\openssl\include;
set LIB=F:\icu\lib;F:\gles_sdk\x86;F:\openssl\lib;
"D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86

上面的路徑請自行換成對應的目錄。然後就可以configure了:

configure -prefix D:\Qt\Static541_2013 -debug-and-release -opensource -static -nomake examples -no-compile-examples -opengl desktop -openvg -platform win32-msvc2013 -target xp -sse4.2 -no-avx -no-avx2 -icu -openssl-linked

configure完直接nmake 然後nmake install,經過漫長的等待,沒問題的話在D:\Qt\Static541_2013就可以看到編譯好的lib了。
這時候靜態版本的Qt已經編譯好了,接下來就該搞webkit了。
編譯完之後不要關閉命令提示符,接著執行以下幾條命令:

set PATH=%PATH%D:\Qt\Static541_2013\bin;F:\qt-everywhere-opensource-src-5.4.1\gnuwin32\bin;
set INCLUDE=%INCLUDE%D:\Qt\Static541_2013\include;
set LIB=%LIB%D:\Qt\Static541_2013\lib;D:\Qt\Static541_2013\plugins;D:\Qt\Static541_2013\plugins\audio;D:\Qt\Static541_2013\plugins\bearer;D:\Qt\Static541_2013\plugins\designer;D:\Qt\Static541_2013\plugins\geoservices;D:\Qt\Static541_2013\plugins\iconengines;D:\Qt\Static541_2013\plugins\imageformats;D:\Qt\Static541_2013\plugins\mediaservice;D:\Qt\Static541_2013\plugins\platforms;D:\Qt\Static541_2013\plugins\playlistformats;D:\Qt\Static541_2013\plugins\position;D:\Qt\Static541_2013\plugins\printsupport;D:\Qt\Static541_2013\plugins\qml1tooling;D:\Qt\Static541_2013\plugins\qmltooling;D:\Qt\Static541_2013\plugins\sensorgestures;D:\Qt\Static541_2013\plugins\sensors;

最後那個set命令中的一大堆plugin的lib目錄應該是不用加的,qmake會自己找到這些lib,但是我沒測試過(也不想去試),誰有興趣可以試試..然後就是編譯webkit了..

perl F:\qt-everywhere-opensource-src-5.4.1\qtwebkit\Tools\Scripts\build-webkit --qt --prefix=d:\Qt\QtWebkit

這裡的prefix好像加和不加都一個樣,反正編譯完都會自動把生成的lib給放到Qt SDK的目錄下,這個prefix指定的目錄卻什麼也沒有。炒雞漫長的等待..看機器效能,我反正是編譯了大約5、6個小時,期間機器卡的不行,就只能看個網頁或者電子書。
編譯還算順利,只遇到了一個錯誤,原因是沒有判斷是否是靜態編譯,用了dllimport: enter image description here

開啟F:\qt-everywhere-opensource-src-5.4.1\qtwebkit\Source\WebCore\platform\qt\QtTestSupport.h,把

#if defined(BUILDING_WEBKIT)
#define TESTSUPPORT_EXPORT Q_DECL_EXPORT
#else
#define TESTSUPPORT_EXPORT Q_DECL_IMPORT
#endif

改成:

#if defined(BUILDING_WEBKIT)
#define TESTSUPPORT_EXPORT /*Q_DECL_EXPORT*/
#else
#define TESTSUPPORT_EXPORT /*Q_DECL_IMPORT*/
#endif

重新執行上面的編譯命令,一路順暢,終於編譯完了...編譯完成後他會自動把qtwebkit的lib拷貝到你的qt sdk所在的目錄,接下來就是配置qt creator或者qt vs plugin了,沒什麼好說的了

我試著編譯了一下qt example中的browser專案,得到了一個51.1mb的exe,upx -9一下就成了16.6m,除了我手殘編譯qt的時候忘了加openssl所以不能訪問https的網站之外功能沒有缺失(上面教程是按照加了openssl來寫的),我也懶得再編譯了,有空再說吧。

另外根據我編譯qt得出的經驗,一般Qt5.X.0編譯都或多或少有各種問題,要麼語法問題,要麼少東西,要麼路徑不對,但是過不久會放出一個5.X.1和5.X.2就一般沒什麼問題了,為什麼會這樣就不知道了。

相關文章