使用预编译头文件

预编译头文件(PCH)是某些编译器支持的一种性能特性,可用于编译稳定的代码体,并将代码的编译状态存储在二进制文件中。在后续编译过程中,编译器将加载存储的状态,并继续编译指定文件。由于无需重新编译稳定的代码,因此每次后续编译都会更快。

qmake 支持在某些平台和编译环境下使用预编译头文件,包括

  • Windows
    • nmake
    • Visual Studio 项目(VS 2008 及更高版本)
  • macOS、iOS、tvOS 和 watchOS
    • Makefile
    • Xcode
  • Unix
    • GCC 3.4 及以上版本
    • clang

在项目中添加预编译头文件

预编译头文件必须包含整个项目中稳定静态的代码。典型的预编译头文件如下所示:

// Add C includes here

#if defined __cplusplus
// Add C++ includes here
#include <stdlib>
#include <iostream>
#include <vector>
#include <QApplication> // Qt includes
#include <QPushButton>
#include <QLabel>
#include "thirdparty/include/libmain.h"
#include "my_stable_class.h"
...
#endif

注意: 预编译头文件需要将 C 包含与 C++ 包含分开,因为 C 文件的预编译头文件可能不包含 C++ 代码。

项目选项

要让项目使用预编译头文件,只需在项目文件中定义PRECOMPILED_HEADER变量:

PRECOMPILED_HEADER = stable.h

qmake 会处理其余部分,确保创建和使用预编译头文件。你不需要在HEADERS 中包含预编译头文件,因为如果配置支持预编译头文件,qmake 就会这样做。

针对 Windows 的 MSVC 和 g++ 规范默认启用precompile_header

使用此选项,您可以在项目文件中触发条件块,以便在使用预编译头文件时添加设置。例如

precompile_header:!isEmpty(PRECOMPILED_HEADER) {
DEFINES += USING_PCH
}

要在 MSVC nmake 目标机的 C 文件中也使用预编译头文件,请在CONFIG变量中添加precompile_header_c 。如果头文件也用于 C++,并且包含 C++ 关键字/包含项,请用#ifdef __cplusplus) 将它们括起来。

关于可能出现的问题的说明

在某些平台上,预编译头文件的文件名后缀与其他对象文件的文件名后缀相同。例如,以下声明可能导致生成两个同名的不同对象文件:

PRECOMPILED_HEADER = window.h
SOURCES            = window.cpp

为避免类似的潜在冲突,请为将被预编译的头文件赋予不同的名称。

示例项目

您可以在 Qt XML 发行版的examples/qmake/precompile 目录中找到以下源代码:

mydialog.ui

下图显示了Qt Creator 设计模式下的 mydialog.ui 文件。您可以在编辑模式下查看代码。

stable.h

/* Add C includes here */

#if defined __cplusplus
/* Add C++ includes here */

# include <iostream>
# include <QApplication>
# include <QPushButton>
# include <QLabel>
#endif

myobject.h

#include <QObject>

class MyObject : public QObject
{
public:
    MyObject();
    ~MyObject();
};

myobject.cpp

#include <iostream>
#include <QDebug>
#include <QObject>
#include "myobject.h"

MyObject::MyObject()
    : QObject()
{
    std::cout << "MyObject::MyObject()\n";
}

util.cpp

void util_function_does_nothing()
{
    // Nothing here...
    int x = 0;
    ++x;
}

main.cpp

#include <QApplication>
#include <QPushButton>
#include <QLabel>
#include "myobject.h"
#include "mydialog.h"

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    MyObject obj;
    MyDialog dialog;

    dialog.connect(dialog.aButton, SIGNAL(clicked()), SLOT(close()));
    dialog.show();

    return app.exec();
}

precompile.pro

TEMPLATE  = app
LANGUAGE  = C++
CONFIG   += cmdline precompile_header

# Use Precompiled headers (PCH)
PRECOMPILED_HEADER  = stable.h

HEADERS   = stable.h \
            mydialog.h \
            myobject.h
SOURCES   = main.cpp \
            mydialog.cpp \
            myobject.cpp \
            util.cpp
FORMS     = mydialog.ui

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.