使用预编译头文件

预编译头文件(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 文件也使用预编译头文件,请将 precompile_header_c 添加到 CONFIG 变量中。如果头文件也用于 C++ 并且包含 C++ 关键字/包含,请用 #ifdef __cplusplus 包围它们。

可能出现的问题说明

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

PRECOMPILED_HEADER = window.h
SOURCES            = window.cpp

为了避免此类潜在冲突,请给将被预编译的头文件起独一无二的名称。

示例项目

您可以在 Qt 分发中的 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

© 2024 Qt公司。本文档中包含的贡献属于各自所有者的版权。本提供的文档按照自由软件基金会发布的版本1.3的GNU自由文档许可证的条款获得许可。Qt及其相关标志是芬兰以及/或世界其他国家Qt公司的商标。所有其他商标均为各自所有者的财产。