Qt源码在VC环境下编译(以VC14下Qt5.9.1和Qt5.4.0为例,包含icu和QtWebkit模块)
ICU57 + Qt5.9.1 + QtWebKit在VC14下編譯
編譯所需工具
| Qt Source | https://download.qt.io/archive/qt/5.9/ |
| VS Compiler | https://docs.microsoft.com/en-us/visualstudio/install/create-a-network-installation-of-visual-studio |
| Python | https://www.python.org/downloads/ |
| Ruby | https://www.ruby-lang.org/en/downloads/ |
| Perl | https://www.perl.org/get.html |
| ICU | http://site.icu-project.org/download |
總覽(以Qt5.9.1_VC14_release_64bit為例)
工具環(huán)境
- 確保編譯工具安裝目錄為默認(rèn)目錄(C盤),并已將bin路徑加入Windows系統(tǒng)環(huán)境變量Path
編譯目錄結(jié)構(gòu)
Root | |-- 5.9.1_x64.bat |-- ICU_57 | | | `--icu | |-- include | |-- lib64 | |-- bin64 | `-- ... `--qt-everywhere-opensource-src-5.9.1||--qtwebkit`-- ...
編譯腳本(5.9.1_x64.bat)
REM Set up VC14 Tools Command Prompt CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64SET ROOT=%CD% SET QT_SOURCE=%ROOT%\qt-everywhere-opensource-src-5.9.1 SET QT_WORKING=%ROOT%\5.9.1_vc14_64 SET QT_INSTALL=%ROOT%\Qt\Qt5.9.1\5.9.1\msvc2015_64SET ICU_OPT=%ROOT%\ICU_57\icu SET ICU_INCLUDE=%ICU_OPT%\include SET ICU_LIB=%ICU_OPT%\lib64 SET ICU_BIN=%ICU_OPT%\bin64REM Set perl, ruby and python path, for needing them to build the QtWebKit SET PATH=C:\Strawberry\c\bin;C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin;C:\Ruby24-x64\bin;C:\Python27amd64;%PATH%REM Set icu path, for needing it's dll to build something SET PATH=%QT_SOURCE%\qtbase\bin;%QT_SOURCE%\gnuwin32\bin;%ICU_BIN%;%PATH%REM Set the build working directory, so you can build 32/64 at the same time IF EXIST %QT_WORKING% RD /s /q %QT_WORKING% MKDIR %QT_WORKING% CD /d %QT_WORKING%REM Building Qt, Just build "qtbase" and "qttools" CALL %QT_SOURCE%\configure.bat -mp -release -shared -confirm-license -platform win32-msvc -opensource -prefix %QT_INSTALL% -icu -I %ICU_INCLUDE% -L %ICU_LIB% ICU_LIBS="icudt.lib icuuc.lib icuin.lib" -opengl desktop -nomake examples -nomake tests -no-dbus -skip qtmacextras -skip qtx11extras -skip qtimageformats -skip qtandroidextras -skip qtserialport -skip qtserialbus -skip qtactiveqt -skip qtxmlpatterns -skip qtsvg -skip qtdeclarative -skip qtremoteobjects -skip qtscxml -skip qtpurchasing -skip qtcanvas3d -skip qtgamepad -skip qt3d -skip qtwayland -skip qtconnectivity -skip qtwebsockets -skip qtwebchannel -skip qtsensors -skip qtmultimedia -skip qtspeech -skip qtdatavis3d -skip qtcharts -skip qtwinextras -skip qtgraphicaleffects -skip qtquickcontrols2 -skip qtquickcontrols -skip qtvirtualkeyboard -skip qtlocation -skip qtwebkit -skip qtscript -skip qtwebengine -skip qtwebview -skip qtnetworkauth -skip qttranslations -skip qtdocPAUSE ECHO ON nmake && nmake installREM The current used ICU version is 57.1 COPY /v /y %ICU_BIN%\icudt57.dll %QT_INSTALL%\bin\ COPY /v /y %ICU_BIN%\icuin57.dll %QT_INSTALL%\bin\ COPY /v /y %ICU_BIN%\icuuc57.dll %QT_INSTALL%\bin\PAUSE CALL %QT_WORKING%\qtbase\bin\qmake.exe %QT_SOURCE%\qtwebkit\Webkit.pro nmake && nmake install若編譯工具都按要求安裝,ICU和Qt的源碼也按照相應(yīng)的目錄結(jié)構(gòu)放置,執(zhí)行5.9.1_x64.bat腳本即可編譯Qt的qtbase, qttools, qtwebkit模塊
- 倘若編譯失敗,請閱讀完全文
Qt Source
解壓qt-everywhere-opensource-src-5.9.1.zip
下載 QtWebKit 模塊 https://download.qt.io/archive/qt/5.9/5.9.1/submodules/qtwebkit-opensource-src-5.9.1.zip
- 將qtwebkit-opensource-src-5.9.1.zip解壓,文件夾改名為qtwebkit并復(fù)制到qt-everywhere-opensource-src-5.9.1文件夾下
目錄樹如下所示
qt-everywhere-opensource-src-5.9.1 | |-- ... |-- gnuwin32 |-- qtbase | |-- configure.bat | |-- config_help.txt | |-- configure.exe | `-- mkspecs | | | |-- win32-msvc | |-- common | | | `-- msvc-desktop.conf |-- qtwebkit | | | |-- | `-- ... |-- qtwebengine |-- configure.bat |-- README `-- ...編譯流程簡述
執(zhí)行根目錄下的configure.bat腳本,在該腳本中會調(diào)用qtbase下的configure.bat,而此腳本又會調(diào)用同目錄下的configure.exe
- 在舊版本的qt源碼中,會在qtbase\tools\目錄下看到有個(gè)configure的項(xiàng)目,configure.exe正是由該項(xiàng)目編譯所得。但在Qt5.9.1的源碼中會發(fā)現(xiàn)整個(gè)tools目錄都被移除。(此外還有個(gè)對qt庫的可視化裁剪工具的項(xiàng)目也找不到,不知道是移除還是移動(dòng)到了其他文件夾。)
- 編譯qt時(shí),需要使用的是根目錄下的configure.bat加上編譯參數(shù)來進(jìn)行編譯
在跟目錄和qtbase目錄下會發(fā)現(xiàn)各存在一個(gè)configure文件,此文件為在Linux/Unix系統(tǒng)下編譯時(shí)使用,在Windows系統(tǒng)下無論你在命令行中輸入configure或者configure.bat都會執(zhí)行configure.bat這個(gè)腳本
根目錄下的README和qtbase目錄下的config_help.txt對編譯源碼所需的工具以及對Qt源碼庫的定制參數(shù)做出了詳細(xì)的介紹
- REAME文件主要介紹所需要編譯工具以及其最低版本
- 可在其中看到以下字段
Perl version 5.12 or later [http://www.activestate.com/activeperl/]
Python version 2.7 or later [http://www.activestate.com/activepython/]
Ruby version 1.9.3 or later [http://rubyinstaller.org/]
- 由于官方發(fā)布的Qt5.9.1版本中已經(jīng)移除了QtWebkit模塊,故在README中沒有看到ICU的版本需求說明。(本人使用57.1,有空的同學(xué)可以去嘗試下其他版本的ICU)
ICU version 57.1 [http://site.icu-project.org/download/57#TOC-ICU4C-Download]
- 可在其中看到以下字段
- config_help.txt則對Qt庫自身的編譯參數(shù)作出了說明
- 第三方庫的include,lib文件夾以及l(fā)ibs文件名配置(使用opengssl,icu等庫編譯時(shí)會用上此部分)
- 在config_help.txt中可看到以下說明,
Usage: configure [options] [assignments]
Configure understands variable assignments like VAR=value on the command line.
Each uppercased library name (obtainable with -list-libraries) supports the
suffixes _INCDIR, _LIBDIR, _PREFIX (INCDIR=PREFIX/include, LIBDIR=PREFIX/lib),
_LIBS, and - on Windows and Darwin - _LIBS_DEBUG and _LIBS_RELEASE. E.g.,
ICU_PREFIX=/opt/icu42 ICU_LIBS="-licui18n -licuuc -licudata".
- 按照安裝文檔使用ICU_INCLUDE="icu_dir"這種方法配置include和lib文件夾時(shí)并不能生效(在編譯前檢查時(shí)會報(bào)錯(cuò)),但是可以使用ICU_LIBS="icudt.lib icuuc.lib icuin.lib"來配置需要鏈接的lib文件。因此最終選擇使用
- -I "icu_include_dir" 配置include路徑
- -L "icu_lib_dir" 配置lib路徑
- -l "icudt" -l "icuuc" -l "icuin"配置lib文件
- 按照安裝文檔使用ICU_INCLUDE="icu_dir"這種方法配置include和lib文件夾時(shí)并不能生效(在編譯前檢查時(shí)會報(bào)錯(cuò)),但是可以使用ICU_LIBS="icudt.lib icuuc.lib icuin.lib"來配置需要鏈接的lib文件。因此最終選擇使用
- 此外也可以使用SET VARIABLE=VALUE這種方式配置include和lib路徑
- SET INCLUDE=%INCLUDE%;%ICU_DIST%\include
- SET LIB=%LIB%;%ICU_DIST%\lib
- 在config_help.txt中可看到以下說明,
- 第三方庫的include,lib文件夾以及l(fā)ibs文件名配置(使用opengssl,icu等庫編譯時(shí)會用上此部分)
上面兩行相當(dāng)于在舊的路徑上加上了icu的include和lib路徑
- 僅編譯部分Qt庫(對Qt庫裁剪)
- -nomake <part>
part主要為examples, tests - -skip <module>
基本在源碼根目錄下的每個(gè)一個(gè)文件名都為一個(gè)module(除了 coin 和 gnuwin32) - -no-dbus可以去除進(jìn)程通信相關(guān)的一個(gè)庫
- -no-feature-<feature> 去除某些feature,本人沒有用過該功能
- 當(dāng)需要編譯QtWebkit時(shí),可修改編譯配置相關(guān)源碼進(jìn)行裁剪
[Qt5] 減少dll依賴和大小(特別是webkit的大小和依賴)
- -nomake <part>
- 其他編譯參數(shù)
- -opengl <api>
Windows下常用的參數(shù)為Desktop,嵌入式絕大多數(shù)為es2 - -static-runtime會把windows的runtime庫靜態(tài)鏈接到Qt庫的dll中,也即是說在沒有安裝runtime庫的機(jī)器上,僅有Qt的dll也可以運(yùn)行程序
- -platform <target>
qtbase\mkspecs目錄下的每一個(gè)文件夾名為一個(gè)target,例子中使用win32-msvc這個(gè)target進(jìn)行編譯 - 編譯 Debug 和 Release 版本
- -release
- -debug
- -debug-and-release
三個(gè)參數(shù)三選一即可,(如需要Release版本下的pdb文件,需加上-force-debug-info)
- 編譯 靜態(tài)庫 或 動(dòng)態(tài)庫
- -shared 動(dòng)態(tài)庫
- -static 靜態(tài)庫(注意與-static-runtime的差別,-static意為編譯出來的Qt庫為靜態(tài)庫, 而-static-runtime則是Qt庫靜態(tài)鏈接VC運(yùn)行時(shí)庫)
本人開發(fā)的為大型Windows桌面程序,故而僅需編譯動(dòng)態(tài)庫,也未曾嘗試編譯靜態(tài)庫。但按照本文方法編譯靜態(tài)庫應(yīng)該不會有太大問題。
- -opengl <api>
VS2015 或者 VS2017
安裝
- Visual Studio的安裝只需要機(jī)器可以聯(lián)網(wǎng),一鍵安裝即可,這里就不在多做介紹。
VS2017中使用VC14的編譯工具報(bào)錯(cuò)問題
- 由于VS2017中集成了VC14編譯器,而且VS2017可選擇安裝目錄,可配置安裝模塊等等,有些同學(xué)更傾向于僅安裝了VS2017。在此環(huán)境下使用VC14編譯工具會有些小問題,這應(yīng)該是M$工程師留下的小Bug。
無論是在Start菜單中點(diǎn)擊VS2015 x64 Native Tools Command Prompt還是使用命令行,最終都會使用C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat這個(gè)bat腳本來初始化VC編譯環(huán)境。該腳本中有以下代碼
@echo off REM VC command prompt depends on env. variable installed during VS. This causes VC command prompt to break for C++ Build SKU. REM So if VS is not installed and C++ Build SKU is installed, set appropriate environment for C++ Build SKU by calling into it's batch file. REM C++ Build SKU supports only desktop development environment.if exist "%~dp0..\common7\IDE\devenv.exe" goto setup_VS if not exist "%~dp0..\common7\IDE\wdexpress.exe" goto setup_buildsku:setup_VS- 調(diào)用此腳本時(shí)會在if exist "%~dp0..\common7\IDE\devenv.exe" goto setup_VS處中斷
- 這是因?yàn)閮H安裝了VS2017,也即是說機(jī)器中只有VS2017那一份IDE,所以在C:\Program Files (x86)\Microsoft Visual Studio 14.0\common7\IDE\文件夾下是不會有devenv.exe這個(gè)文件。(%~dp0代指bat腳本文件所在文件夾)
- 解決方法,將這兩句判斷的語句注釋掉即可
bat
REM if exist "%~dp0..\common7\IDE\devenv.exe" goto setup_VS
REM if not exist "%~dp0..\common7\IDE\wdexpress.exe" goto setup_buildsku
Python Ruby Perl
在qtbase\bin文件夾下看到兩個(gè)后綴為pl的文件,在編譯qtbase模塊時(shí)應(yīng)該需要Perl這個(gè)工具。
而在安裝過程中,并沒有仔細(xì)研究過編譯的log,此外也沒有時(shí)間去閱讀Qt源碼。這些工具都是為了編譯哪些模塊則不是太清楚。唯一確定是,如果你想編譯QtWebKit模塊,Python Ruby Perl 和 icu 是必須全部安裝的。
QtWebKit依賴于Qt的其他模塊,若沒有編譯那些模塊就編譯QtWebKit會把那些模塊全部編譯到QtWebKit.dll中。(此項(xiàng)是我想當(dāng)然猜的,有興趣的同學(xué)可以去研究一下,告訴下我正確答案)
如果不需要編譯QtWebKit庫,這個(gè)庫完全不需要安裝。
在網(wǎng)上搜索各種關(guān)于Qt icu的信息,各種搜索結(jié)果搜搞得好復(fù)雜,有些設(shè)置要求你在Windows下安裝一個(gè)Linux環(huán)境。也許是由于搜索了”Qt icu”,所以搜索結(jié)果就變得復(fù)雜了;也有可能是我水平太低,在這之前并不知道ICU是一個(gè)編碼轉(zhuǎn)碼庫…
在官方中下載到ICU的源碼解壓后,可得到以下目錄結(jié)構(gòu)的文件
icu | `--source|`allinone|`--allinone.sln使用VS2015/VS2017打開allinone.sln這個(gè)解決方案,可看到工程中配置的編譯器版本為VC10
除了makedata這個(gè)工程以外,其他工程全部升級VC14
右鍵點(diǎn)擊Solution ‘a(chǎn)llinone’,然后Build Solution
- 在Qt開發(fā)過程中無需對ICU庫Debug,而且編譯Debug/Release版本的Qt庫時(shí)都可使用Release版本的ICU,因此,我們僅需要編譯32/64bit的Release版本的ICU庫
- Qt中僅使用icudt57.dll(stubdata), icuuc57.dll(common), icuin57.dll(i18n)這三個(gè)dll,本人貪圖方便就整個(gè)Solution都進(jìn)行編譯了。但復(fù)制資源,僅復(fù)制這三個(gè)文件到Qt的安裝目錄下的bin文件夾即可。
若ICU編譯成功,可得到icu目錄下會多出以下文件夾
icu | |--source | | | `allinone | | | `--allinone.sln | |--include |--lib |--bin |--lib64 `--bin64
- 初始化編譯環(huán)境
- CALL 'bat' 'value',調(diào)用另外一個(gè)bat腳本,類似于一個(gè)函數(shù)調(diào)用
- SET VAR=value,相當(dāng)于定義變量VAR,并賦予初值value
- %VAR%,則為取VAR的值
- 如下代碼,初始化了VC14_x64編譯環(huán)境,并定義了當(dāng)前的工作路徑,QT的路徑,ICU的路徑以備后用。
將編譯工具加入系統(tǒng)環(huán)境變量
REM Set perl, ruby and python path, for needing them to build the QtWebKit SET PATH=C:\Strawberry\c\bin;C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin;C:\Ruby24-x64\bin;C:\Python27amd64;%PATH%REM Set icu path, for needing it's dll to build something SET PATH=%QT_SOURCE%\qtbase\bin;%QT_SOURCE%\gnuwin32\bin;%ICU_BIN%;%PATH%- 編譯Qt需要Perl, Ruby, Python這三個(gè)工具來做些事情,我們安裝了這些工具后,在編譯Qt時(shí),又是如何找到這些工具的exe來執(zhí)行編譯某些源碼?如果你在安裝這些工具時(shí),提勾了加入系統(tǒng)環(huán)境變量,那么你會在Windows的System Info里面找到如下圖所示的配置。而在Qt的編譯腳本執(zhí)行時(shí),會檢查系統(tǒng)環(huán)境變量的Path里有沒有對應(yīng)的工具。
- 當(dāng)然我們也可以設(shè)置一個(gè)臨時(shí)的PATH。如上述代碼所示,將需要的編譯工具路徑追加在原系統(tǒng)的PATH里(當(dāng)退出當(dāng)前的cmd命令窗口后,這些設(shè)置會被自動(dòng)清除)。
- 在使用-icu編譯的同時(shí),也需要將ICU的dll所在目錄添加到PATH中。(如果我沒有記錯(cuò),在使用-icu編譯時(shí),在編譯widgets模塊時(shí),需要用到ICU的dll來生成某些文件)
- 編譯Qt需要Perl, Ruby, Python這三個(gè)工具來做些事情,我們安裝了這些工具后,在編譯Qt時(shí),又是如何找到這些工具的exe來執(zhí)行編譯某些源碼?如果你在安裝這些工具時(shí),提勾了加入系統(tǒng)環(huán)境變量,那么你會在Windows的System Info里面找到如下圖所示的配置。而在Qt的編譯腳本執(zhí)行時(shí),會檢查系統(tǒng)環(huán)境變量的Path里有沒有對應(yīng)的工具。
設(shè)置編譯QT的工具目錄
REM Set the build working directory, so you can build 32/64 at the same time IF EXIST %QT_WORKING% RD /s /q %QT_WORKING% MKDIR %QT_WORKING% CD /d %QT_WORKING%- 在使用configure.bat編譯時(shí),會在將當(dāng)前的目錄工作,所有生成的中間文件都會放在當(dāng)前目錄,所以需要在一個(gè)工作目錄調(diào)用源碼目錄下configure.bat,這樣可以避免污染源碼。即使在編譯過程中發(fā)生了錯(cuò)誤,我們還是可以刪了工作目錄或者換一個(gè)工作目錄重來。此外,也可以同時(shí)編譯多個(gè)版本(32/64,debug/release,vc140/vc141)的Qt。
Qt編譯參數(shù)設(shè)置
REM Building Qt, Just build "qtbase" and "qttools" CALL %QT_SOURCE%\configure.bat -mp -debug -shared -confirm-license -platform win32-msvc -opensource -prefix %QT_INSTALL% -icu -I %ICU_INCLUDE% -L %ICU_LIB% ICU_LIBS="icudt.lib icuuc.lib icuin.lib" -opengl desktop -nomake examples -nomake tests -no-dbus -skip qtmacextras -skip qtx11extras -skip qtimageformats -skip qtandroidextras -skip qtserialport -skip qtserialbus -skip qtactiveqt -skip qtxmlpatterns -skip qtsvg -skip qtdeclarative -skip qtremoteobjects -skip qtscxml -skip qtpurchasing -skip qtcanvas3d -skip qtgamepad -skip qt3d -skip qtwayland -skip qtconnectivity -skip qtwebsockets -skip qtwebchannel -skip qtsensors -skip qtmultimedia -skip qtspeech -skip qtdatavis3d -skip qtcharts -skip qtwinextras -skip qtgraphicaleffects -skip qtquickcontrols2 -skip qtquickcontrols -skip qtvirtualkeyboard -skip qtlocation -skip qtwebkit -skip qtscript -skip qtwebengine -skip qtwebview -skip qtnetworkauth -skip qttranslations -skip qtdoc PAUSE ECHO ON nmake && nmake install在官方提供的文檔中,可以發(fā)現(xiàn)是沒有對應(yīng)的編譯platform。本人嘗試了多次,也試過修改下Qt的源碼,最終發(fā)現(xiàn)使用-platform win32-msvc2013也是可以編譯vc14版本的Qt。 但還是僅能可以編譯base模塊。另外,qttools下的designer這個(gè)程序也可以編譯通過,但是assistant這個(gè)卻不行,這個(gè)應(yīng)該是Qt5.4.0中的一些C++STL中的模板和容器不支持在VC14上編譯。
由于Qt5.4是一個(gè)過度版本,我就不再在這個(gè)版本多做研究。我在下面給出了編譯腳本,有興趣的同學(xué)可以研究一下。遇到問題,去看看\qtbase\mkspecs\win32-msvc2013和\qtbase\tools\configure下的源碼,應(yīng)該會有所幫助。
REM Set up VC14 Tools Command Prompt CALL "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64SET ROOT=%CD% SET QT_SOURCE=%ROOT%\qt-everywhere-opensource-src-5.4.0 SET QT_WORKING=%ROOT%\5.4.0_vc14_64 SET QT_INSTALL=%ROOT%\Qt\Qt5.4.0\5.4.0\msvc2015_64REM Set icu path, for needing it's dll to build something SET PATH=%QT_SOURCE%\qtbase\bin;%QT_SOURCE%\gnuwin32\bin;%PATH%REM Set the build working directory, so you can build 32/64 at the same time IF EXIST %QT_WORKING% RD /s /q %QT_WORKING% MKDIR %QT_WORKING% CD /d %QT_WORKING%CALL %QT_SOURCE%\configure.bat -mp -debug -shared -confirm-license -platform win32-msvc2013 -opensource -prefix %QT_INSTALL% -opengl desktop -nomake examples -nomake tests -skip qtandroidextras -skip qtmacextras -skip qtx11extras -skip qtsvg -skip qtxmlpatterns -skip qtdeclarative -skip qtquickcontrols -skip qtmultimedia -skip qtwinextras -skip qtactiveqt -skip qtlocation -skip qtsensors -skip qtconnectivity -skip qtwebsockets -skip qtwebchannel -skip qtwebkit -skip qtwebkit-examples -skip qtimageformats -skip qtgraphicaleffects -skip qtscript -skip qttools -skip qtquick1 -skip qtserialport -skip qtenginio -skip qtwebengine -skip qttranslations -skip qtdocECHO ON nmake && nmake installcd %QT_SOURCE%\qttools\src\designer CALL %QT_WORKING%\qtbase\bin\qmake.exe designer.pro nmake && nmake installcd %QT_SOURCE%\qttools\src\linguist CALL %QT_WORKING%\qtbase\bin\qmake.exe linguist.pro nmake && nmake installVisual Studio 2015編譯安裝配置QT5.5.1(含QTWEBKIT)
msvc2013編譯qt5.6源碼
自編譯QT中的ICU庫問題
用msvc2008編譯qt5.4.0
[Qt5] 減少dll依賴和大小(特別是webkit的大小和依賴)
VS2017自帶VS2015編譯器等在命令行下無法使用問題
Create an offline installation of Visual Studio 2017
Bat命令學(xué)習(xí)
Markdown Src: https://github.com/joshion/CSDN.git
ICU
編譯腳本編寫
我們可以不學(xué)習(xí)OOP編程技術(shù),但是我們絕不能不遵守SOP(SB Oriented Programming)編程準(zhǔn)則–軟件設(shè)計(jì)的終極目標(biāo)就是“不但SB會用你的程序,而且SB也能看懂你的代碼”。因此最后,我還是對文章開頭的腳本作下說明。
Qt5.4.0 VC14下編譯
Referene
總結(jié)
以上是生活随笔為你收集整理的Qt源码在VC环境下编译(以VC14下Qt5.9.1和Qt5.4.0为例,包含icu和QtWebkit模块)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS-几类函数
- 下一篇: SpringBoot在自定义类中调用se