本篇參考了知乎文章 https://www.zhihu.com/question/23045749
,然後個人精心整理而來,Windows使用者請重點關注方法7,效果立竿見影!
通常大家會認為Qt Creator的編譯速度太慢,太耗時間。容易讓人産生誤會,即“用Qt寫的程式編譯比MFC慢”。其實這個說法是錯誤的。首先,Qt creator隻是一個IDE,不是編譯器,編譯快慢與Qt Creator無關,要看具體使用的是什麼編譯器和程式設計方法。
事實上,機關代碼行數編譯Qt遠比MFC快得多,因為Qt庫的頭檔案設計非常好,盡量都使用了前置聲明,避免了頭檔案嵌套,幾乎所有類都使用了公有類和私有類的設計,把沒必要公開的聲明放到私有頭檔案裡,避免了編譯時引入過多代碼。而MFC沒有這樣的設計。至于大家感覺MFC快主要原因是MFC工程預設打開了編譯預處理頭檔案(PCH),但是這不僅僅是VC編譯器的特性,所有C++程式都可以用,不是MFC特有,Qt也可以使用 PCH。
方法1:工程.pro檔案加入預編譯機制,PRECOMPILED_HEADER
詳情見官網介紹:
https://doc.qt.io/qt-5/qmake-precompiledheaders.html https://doc.qt.io/qt-5/qmake-variable-reference.html#configQt安裝路徑也有具體的示例,例如筆者的路徑是D:\Qt\Qt5.9.8\Examples\Qt-5.9.8\qmake\precompile
下面我們說說使用方法,添加預編譯頭檔案(PCH,PreCompiled Headers)支援,在pro檔案添加下面代碼:
# Use Precompiled headers (PCH)
CONFIG += precompile_header
PRECOMPILED_HEADER = stable.h
# HEADERS += stable.h #這句話是可有可無的,建議加上
預編譯頭檔案stable.h包含哪些内容?預編譯頭檔案應該将穩定和靜态(例如,Qt庫頭檔案、第三方庫頭檔案、自定義的不經常改動的頭檔案)的代碼包含在你工程中。一個典型的PCH檔案類似如下:
// #ifndef STABLE_H //Qt官方例子沒有定義這個條件編譯
// #define STABLE_H
// Add C includes here
#include <iostream>
#if defined __cplusplus
// Add C++ includes here
#include <vector>
// Qt includes
#include <QApplication>
// #include <QtCore> //請謹慎包含
// #include <QtGui> //請謹慎包含
#include <QObject>
#include <qglobal.h>
#include <QDir>
#include <QIntValidator>
#include <QToolTip>
#include <QDebug>
#include <QMainWindow>
#include <QDialog>
#include <QFileDialog>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QTimer>
#include <QtNetwork>
#include <QTextCodec>
#include <QThread>
#include <QtSql>
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
#include <QtWidgets>
#endif
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QGraphicsPixmapItem>
#include <QGraphicsSceneWheelEvent>
// Other
#include "thirdparty/include/libmain.h"
#include "my_stable_class.h"
...
#endif //__cplusplus
// #endif // STABLE_H
注意:
1、如果可以的話,請盡量不要#include <QtCore>和#include <QtGui>,因為這兩個頭檔案涵蓋了Qt所有的類,處理他們需要的時間相當長。
2、官方文檔說,預編譯頭檔案要将C和C++頭檔案分開,是以使用了#if defined __cplusplus
3、我發現Qt官方自帶的案例
https://github.com/qt/qtbase/blob/5.12/examples/qmake/precompile/stable.h(在本地安裝路徑也有\Examples\Qt-5.9.8\qmake\precompile),以及Qt Creator的源碼
https://github.com/qt-creator/qt-creator/blob/master/src/shared/qtcreator_pch.h都沒有使用“防止頭檔案重複包含”的宏定義:言外之意,預編譯頭檔案允許重複包含了?有待确認..fixme..
#ifndef STABLE_H
#define STABLE_H
#endif
在.pro檔案添加預編譯資訊之後,qmake将會處理剩下的工作——確定建立和使用預編譯頭檔案。你不需要在.pro檔案包含預編譯頭檔案到HEADERS變量中,如果配置了支援PCH,qmake會幫助你完成這些。
如果是VC++編譯器,最終會生成{projectname}_pch.pch檔案,大約幾十或上百M的預編譯頭檔案。
如果是MinGW編譯器,最終會生成stable.h.gch檔案夾,裡面有個C++檔案,大約幾十或上百M的預編譯頭檔案。
未開啟Qt的預編譯頭檔案功能時,項目一旦工程數目衆多,每個工程中又有很多檔案時,每個頭檔案交叉包含Qt的頭檔案、第三方頭檔案、自定義的頭檔案。一旦啟動編譯,過程是漫長又痛苦的!
開啟Qt預編譯頭檔案後,同樣的項目編譯下來不需要漫長的等待時間,項目即可編譯完成。與未使用預編譯頭檔案之前相比,速度上快了10倍以上!
4、更詳細的.pro檔案的配置,請參見我的另一篇部落格
Qt Creator指定臨時檔案生成目錄(MOC_DIR/RCC_DIR等)和配置.pro檔案
方法2:啟動多核編譯
1、如果是VS的MSVC編譯器,可以在 .pro裡加入下面一行
QMAKE_CXXFLAGS += /MP
指定/mp編譯選項,編譯器将使用并行編譯,同時起多個編譯程序并行編譯不同的cpp。
2、如果是MinGW編譯器:
項目-》建構設定-》建構步驟-》make詳情-》make參數 ,填入-j4,之後編譯就飕飕的了,如果處理器八個核填-j8。
筆者注:本人發現Qt Creator 4.8.2 (Enterprise)及以上版本已經預設啟動了多核編譯,無需自己手動設定了。(#^.^#)
方法3:添加-r參數(僅針對MinGW有效,VC++無效)
QtCreator在windows下用Mingw編譯的時候,在正式開始編譯前,會卡一段時間,大概10s左右的樣子,是以對小工程就可能造成編譯速度慢的假象,如果是這個情況,你需要在make和clean的參數選項前加個 “-r” ,這樣就會直接開始編譯工作,速度馬上就會快很多了。
方法4:頭檔案包含,盡量用類的前置聲明代替#include
例如,頭檔案include <class_> 改成 class class_
詳情參見我的另一篇部落格:
https://blog.csdn.net/libaineu2004/article/details/89207060方法5:Windows使用者請采用Visual Studio的msvc編譯器,而不是MinGW的gcc編譯器。前者比後者編譯速度更快。
一般來說Windows下就是MinGW的gcc和Visual Studio/MSVC的nmake,在Windows下推薦使用MSVC編譯器nmake,能夠加快編譯速度。
MinGW,其實它就是一個移植版本的GCC,的确是不如VC++快的。如果是其它平台,那麼編譯器可以換成LLVM的clang,那就快很多了。同樣的源碼,在MacOS編譯比Windows要快得多,因為MacOS使用的就是Clang編譯器。
是以結論:在Windows平台還是盡量用MSVC編譯器!另外,有經濟條件的話,建議使用MacOS開發,編譯快。
方法6:關閉360殺毒防護軟體的實時掃描功能,或者啟用開發者模式,信任編譯輸出路徑。
方法7:Windows使用者可以使用第三方插件,IncrediBuild for Qt Creator
詳情參見我的另一篇部落格:《提高Qt Creator編譯速度的7種方法の擴充篇:IncrediBuild v9.x使用詳解,與Qt Creator v4.10搭配提速》
其他方法:比如有經濟條件的話,使用固态硬碟,這對提升編譯速度也很明顯。
-------------------------------------------------------附錄-------------------------------------------------------------
題外話:
1、解決windows下vc++編譯器qDebug()等中文亂碼問題,可以在stable.h中添加:
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
# pragma execution_character_set("utf-8")
或者
#ifdef _MSC_VER
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#pragma warning (disable:4819)
#endif // _MSC_VER >= 1600
#endif // _MSC_VER
注意: Qt Creator -> Options -> Text Editor -> Behavior -> File Encodings 更改設定為 "UTF-8",BOM設定為"Add If Encoding Is UTF-8",如果編碼是UTF-8則添加。
2、場景證明
情景一:今天在使用Qt設計界面的時候發現的一個問題,每修改一處代碼,就要清理工程、重新建構才可以看到最新的效果
項目檔案少還好,檔案多了,每修改一下就要重新建構一次,特别浪費時間!
情景二:由于vc2013開始可以使用"#pragma execution_character_set("UTF-8")"來解決UTF-8編碼問題,可是這句話放哪裡呢?網上查一查,清一色的都說放在main函數前面,好吧,我放了,但是發現還是會存在亂碼的問題。其實網上那些朋友搞錯了一個概念,這個指令是在編譯時産生作用的,而不是運作時,你放main函數前面根本就沒用!你要放在編譯器編譯的第一個檔案中頭部,但是問題是你不确定編譯器到底從哪個檔案開始編譯。。。
基于以上兩個不便之處,預編譯頭檔案的作用就顯現出來了!
3、筆者發現小問題
使用環境是Qt Creator 4.8.2+MSVC2015編譯器,編譯工程時,有時.pch檔案會生成在目前建構目錄下,名字是{projectname}_pch.pch;有時會生成在C:\Users\<使用者名>\AppData\Local\Temp,而且名字是随機的。奇怪了。。囧
4、VC++預編譯頭檔案 – stdafx.h的作用是什麼?
https://blog.csdn.net/libaineu2004/article/details/914285955、Qt Creator斷點調試慢?
IDE菜單->工具->選項->建構和運作,在部署項目前總是先建構&在運作項目前總是先部署,這兩欄去掉勾選再試試。
6、C++庫大全
https://github.com/fffaraz/awesome-cpp