本篇参考了知乎文章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#config
Qt安装路径也有具体的示例,例如笔者的路径是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会帮助你完成这些。
# HEADERS += stable.h #这句话是可有可无的,建议加上
如果是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")
#endif
或者
#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/91428595
5、Qt Creator断点调试慢?
IDE菜单->工具->选项->构建和运行,在部署项目前总是先构建&在运行项目前总是先部署,这两栏去掉勾选再试试。
6、C++库大全
https://github.com/fffaraz/awesome-cpp