Qt 之 Qt/Qt Lite 自编译详解(VS/MinGW/...)
- 2018/3/24 目前QT更新到了5.10.1。文章增加了對該版本的說明。
- 2020/9/5 目前QT更新到了5.15.0。文章更新了部分內容
寫在前面
??現在,網上關于 Qt 編譯的文章數不勝數。寫這篇文章僅僅是對于自我學習的一個記錄。主要是對實際學習中遇到的一些棘手問題做個備忘錄。
??編譯工具使用 VS2017 和 MinGW5.3.0 為例,來進行說明。
qconfig-gui
??如果使用的是 Qt 的商業版,會提供一個叫做 Qt Configuration Tool 的 GUI 工具。我們可以使用它更方便的來生成 Configure 參數。省去了我們自己摸索 configure 參數的煩惱。如下圖:
我們選擇好配置之后,點擊 工具里的 Run Configure 就會自動執行 Configure。需要注意的是,Feature 需要執行操作之后才會顯示(處理了 qtbase 之后)。 如果使用的是開源版,就只能按照后文一點點自己摸索了!
Qt Configure
??Qt 的配置系統可以說相當復雜。看完源碼中的各種配置文件,自殺的心都有了。。。
??在Qt的眾多配置選項中,有些是固定針對特定平臺的;有些是自動檢測的; 對于以上兩種,一般不需要太關心。需要關注的配置選項中,個人感覺需要重點關注的可以分為以下三大類種:
- 基本配置選項
- Qt 組件配置選項(Qt Modules、Qt Features等)
- Third-Party Libraries配置參數
??當編譯目錄和源碼目錄不一樣時,稱為 影子編譯(shadow build) 。(Qt Creator 默認是使用影子編譯來編譯工程的)。Qt 源碼的編譯也可以使用影子編譯,方法就是新建一個目錄,然后 cd 到該目錄中運行 configure。影子編譯在處理一份源碼對應多種編譯結果時尤為方便。
mkdir ~/qt-build cd ~/qt-build ~/qt-source/configure -prefix /opt/Qt5.6 /* 在新建的目錄中執行編譯,則編譯產生的文件就會放在新目錄,不會對源碼目錄有影響 */基本配置選項
??基本配置選項主要就是Build options 和 Build environment。這兩部分給出了我們要如何編譯 Qt 源碼。主要的參數項目(部分)如下:
Build options:-opensource .......... Build the Open-Source Edition of Qt-commercial .......... Build the Commercial Edition of Qt-confirm-license ..... Automatically acknowledge the license-release ............. Build Qt with debugging turned off [yes]-debug ............... Build Qt with debugging turned on [no]-debug-and-release ... Build two versions of Qt, with and withoutdebugging turned on [yes] (Apple and Windows only)-optimize-debug ...... Enable debug-friendly optimizations in debug builds[auto] (Not supported with MSVC)-optimize-size ....... Optimize release builds for size instead of speed [no]-optimized-tools ..... Build optimized host tools even in debug build [no]-force-debug-info .... Create symbol files for release builds [no]-separate-debug-info . Split off debug information to separate files [no]-strip ............... Strip release binaries of unneeded symbols [yes]-force-asserts ....... Enable Q_ASSERT even in release builds [no]-developer-build ..... Compile and link Qt for developing Qt itself(exports for auto-tests, extra checks, etc.) [no]-shared .............. Build shared Qt libraries [yes] (no for UIKit)-static .............. Build static Qt libraries [no] (yes for UIKit)-framework ........... Build Qt framework bundles [yes] (Apple only)-platform <target> ... Select host mkspec [detected]-xplatform <target> .. Select target mkspec when cross-compiling [PLATFORM]-device <name> ....... Cross-compile for device <name>-device-option <key=value> ... Add option for the device mkspecBuild environment:-sysroot <dir> ....... Set <dir> as the target sysroot-gcc-sysroot ......... With -sysroot, pass --sysroot to the compiler [yes]-pkg-config .......... Use pkg-config [auto] (Unix only)-D <string> .......... Pass additional preprocessor define-I <string> .......... Pass additional include path-L <string> .......... Pass additional library path-F <string> .......... Pass additional framework path (Apple only)-sdk <sdk> ........... Build Qt using Apple provided SDK <sdk>. The argumentshould be one of the available SDKs as listed by'xcodebuild -showsdks'.Note that the argument applies only to Qt librariesand applications built using the target mkspec - nothost tools such as qmake, moc, rcc, etc.-android-sdk path .... Set Android SDK root path [$ANDROID_SDK_ROOT]Qt 組件配置選項
??該部分主要就是 Qt Modules 配置參數、Qt Features 配置參數 、Qt Parts 等等。其中,Qt Features 即從 Qt 忘了幾開始,官方出的 Qt Lite配置系統 針對的部分。
Qt Modules
??關于Qt各模塊的詳細說明,感興趣的可以去http://doc.qt.io/qt-5/qtmodules.html查看。針對這一部分,Qt Configure中通常可以使用以下命令進行裁剪:configure -skip moudule
??查看 Qt 源碼不難發現,基本每個模塊就對應了 Qt 源碼根目錄下的一個文件夾,所為 skip 某個模塊,就是跳過對應的某個目錄。 例如:Qt的 qtconnectivity 模塊及對應了 Qt 源碼目錄的 qtconnectivity 文件夾。查看該文件夾中可發現,其中有 bluetooth 和 nfc。這也就表明了,如果不編譯該模塊,這就沒有藍牙和NFC。
注意:
Qt Features
??上面說了,在Qt源碼根目錄下,每個文件夾都是Qt的一個模塊,其中就有個qtbase的文件夾,看名字就知道這是Qt的基本組成部分,該目錄下,也有一些可以精簡的Qt 模塊。其實之前也是可以精簡該部分中的某些子項目的,只是通過幾個參數而已,現在,官方給出了新的配置系統,即為:Qt Lite Project。
??關于這部分,主要就是 Qt Lite 配置系統 。開始,我還以為Qt Lite是一個精簡的Qt版本 或者說一個可以精簡Qt的工具。最早官方也沒有專門的文檔對這部分進行說明,后續才出了些文檔。看了好多文檔后,終于有了個大體的了解。針對這一部分,Qt Configure中通常可以使用以下命令進行裁剪:
??在最新的Qt5.9.1源碼中,qtbase/src/corelib/global/qfeatures.txt一不存在了,至少我沒找到。但是現在,可以通過以下命令,直接查看列表:configure --list-features。如下圖為部分列表
??在Qt5.10.0源碼中,執行命令configure --list-features會報錯!
Qt Parts
??在Qt的配置選項中,有幾個參數是針對于Qt Parts List的。但是,具體這個Parts列表中都有啥我也沒有搞清楚。
Third-Party Libraries
??Qt源碼中包含了一些第三方庫,如果想使用Qt自帶的第三方庫,可用通過-qt配置;不需要使用對應模塊時,使用-no+模塊名;如果想使用系統中的第三方庫,可用通過-system配置。下表中列出一些第三方庫及其配置選項:
| zlib | -qt-zlib | -system-zlib |
| libjpeg | -qt-libjpeg | -system-libjpeg |
| libpng | -qt-libpng | -system-libpng |
| xcb | -qt-xcb | -system-xcb |
| xkbcommon | -qt-xkbcommon | -system-xkbcommon |
| freetype | -qt-freetype | -system-freetype |
| PCRE | -qt-pcre | -system-pcre |
| HarfBuzz-NG | -qt-harfbuzz | -system-harfbuzz |
??針對這部分,可以使用一下命令:./configure -no-zlib -qt-libjpeg -qt-libpng -system-xcb
Qt5.9.1靜態編譯選項
??以下命令參數進行了大量裁剪,可根據自己的需要修改。例如以下裁剪后,導致編譯出來的程序不能正確處理Qss中,color:white;這樣的屬性,必須使用color:grb(255,255,255)這樣。因為裁剪掉了colornames這個特性。
MSVC2017 編譯:
采用 MinGW 編譯:
configure.bat -static -release -platform win32-g++ -no-opengl -prefix "F:\Qt5.9.1_MinGW5.3.0_x86_Static" -opensource -confirm-license -make libs -nomake tools -nomake examples -nomake tests -skip qt3d -skip qtandroidextras -skip qtcanvas3d -skip qtconnectivity -skip qtdatavis3d -skip qtdeclarative -skip qtdoc -skip qtgamepad -skip qtcharts -skip qtgraphicaleffects -skip qtimageformats -skip qtlocation -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquickcontrols -skip qtquickcontrols2 -skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtspeech -skip qtsvg -skip qttools -skip qttranslations -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtwinextras -skip qtx11extras -skip qtxmlpatterns -no-feature-texthtmlparser -no-feature-textodfwriter -no-feature-concurrent -no-feature-effects -no-feature-sharedmemory -no-feature-systemsemaphore -no-feature-im -no-feature-dom -no-feature-filesystemwatcher -no-feature-graphicsview -no-feature-graphicseffect -no-feature-sizegrip -no-feature-printpreviewwidget -no-feature-keysequenceedit -no-feature-colordialog -no-feature-fontdialog -no-feature-printpreviewdialog -no-feature-progressdialog -no-feature-inputdialog -no-feature-errormessage -no-feature-wizard -no-feature-datawidgetmapper -no-feature-colornames -no-feature-cups -no-feature-paint_debug -no-feature-codecs -no-feature-big_codecs -no-feature-iconv -no-feature-ftp -no-feature-networkproxy -no-feature-socks5 -no-feature-networkdiskcache -no-feature-bearermanagement -no-feature-completer -no-feature-fscompleter -no-feature-mimetype -no-feature-undocommand -no-feature-undostack -no-feature-undogroup -no-feature-undoview -no-feature-statemachine -no-feature-gestures -no-feature-dbusQt5.9.4 靜態編譯選項
??在編譯 Qt5.9.4 時,發現以上這些參數在編譯是通不過的!例如:
- -no-feature-ftp會導致\qtbase\src\network\access\qnetworkaccessfilebackend.cpp(243): error C2027: use of undefined type 'QDateTime'
和\qtbase\include\qtcore\../../src/corelib/io/qfileinfo.h(53): note: see declaration of 'QDateTime' - -no-feature-completer會導致\qtbase\src\widgets\util\qcompleter.h(50): error C2338: Required feature completer for file e:\code\qt_src\src5.10.1\qtbase\src\widgets\util\qcompleter.h not available.
經過多次嘗試,最終發現的的編譯選項如下:
MSVC2017編譯:
.\..\src\configure.bat -static -release -platform win32-msvc -no-opengl -prefix "D:\Qt\Qt5.9.4\5.9.4\Qt5.9.4_MSVC2017_x86_Static" -opensource -confirm-license -make libs -nomake tools -nomake examples -nomake tests -skip qt3d -skip qtandroidextras -skip qtcanvas3d -skip qtconnectivity -skip qtdatavis3d -skip qtdeclarative -skip qtdoc -skip qtgamepad -skip qtcharts -skip qtgraphicaleffects -skip qtimageformats -skip qtlocation -skip qtmacextras -skip qtmultimedia -skip qtnetworkauth -skip qtpurchasing -skip qtquickcontrols -skip qtquickcontrols2 -skip qtscript -skip qtscxml -skip qtsensors -skip qtserialbus -skip qtspeech -skip qtsvg -skip qttools -skip qttranslations -skip qtvirtualkeyboard -skip qtwayland -skip qtwebchannel -skip qtwebengine -skip qtwebsockets -skip qtwebview -skip qtwinextras -skip qtx11extras -skip qtxmlpatterns -no-feature-texthtmlparser -no-feature-textodfwriter -no-feature-concurrent -no-feature-effects -no-feature-sharedmemory -no-feature-systemsemaphore -no-feature-im -no-feature-dom -no-feature-filesystemwatcher -no-feature-graphicsview -no-feature-graphicseffect -no-feature-sizegrip -no-feature-printpreviewwidget -no-feature-keysequenceedit -no-feature-colordialog -no-feature-fontdialog -no-feature-printpreviewdialog -no-feature-progressdialog -no-feature-errormessage -no-feature-wizard -no-feature-datawidgetmapper -no-feature-cups -no-feature-paint_debug -no-feature-codecs -no-feature-big_codecs -no-feature-iconv -no-feature-networkproxy -no-feature-socks5 -no-feature-networkdiskcache -no-feature-bearermanagement -no-feature-mimetype -no-feature-undocommand -no-feature-undostack -no-feature-undogroup -no-feature-undoview -no-feature-statemachine -no-feature-gestures -no-feature-dbus -no-feature-sessionmanager -no-feature-topleveldomain -no-feature-sha3-fast -no-feature-imageformat_ppm -no-feature-imageformat_xbm -no-feature-highdpiscaling -no-feature-freetype -no-feature-appstore-compliant -no-feature-process -no-feature-lcdnumberQt5.10.1靜態編譯選項
??其編譯選項與 Qt5.9.4 是一樣的。原先好多參數取消后會導致錯誤!
Qt5.15.0靜態編譯選項
??其編譯選項與 Qt5.9.4 是一樣的。原先好多參數取消后會導致錯誤!
Qt5兼容XP方法
??主要針對在使用VS編譯時。默認情況下,最新的VS編譯器沒有開啟對于xp的支持。
??在編譯Qt源碼時,修改qtbase\mkspecs\common\msvc-desktop.conf中的如下部分:
??QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.01,即可使編譯出來的Qt支持xp。
??如果沒有以上編譯源碼,也可以在寫程序時,在pro文件中加一句:QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.01
Qt5靜態編譯后使用錯誤
??正常編譯完成,添加到Qt Creator后,可能會提示如下錯誤:Qt version is not properly installed,please run make install
??原因是qmake.exe是在Qt編譯安裝時生成的,里面內嵌了Qt相關的一些路徑。移動路徑后與原來不同,則Qt庫就不能正常使用。也就是說,如果不更改編譯時指定的的安裝路徑是沒問題。
??解決方法很簡單,可以直接patch一下qmake.exe。還有個更簡單的方法:在qmake.exe同一文件夾下,創建一個qt.conf文件。qt.conf的內容如下:
Qt5 VS編譯亂碼
??使用MSVC編譯Qt程序或者用Qt Creator打開VS的源碼文件時,中文顯示為亂碼。這主要是由于文件編碼導致的。
關于這部分可以看:
http://zcshou.blog.163.com/blog/static/23843807120176273845167/
總結
以上是生活随笔為你收集整理的Qt 之 Qt/Qt Lite 自编译详解(VS/MinGW/...)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C/C++之 C++ String(字符
- 下一篇: FreeRTOS 低功耗之 tickle