> For the complete documentation index, see [llms.txt](https://tyw66.gitbook.io/qmake_manual_cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tyw66.gitbook.io/qmake_manual_cn/yong-hu-shou-ce/di-9-zhang-shi-yong-yu-bian-yi-de-tou-wen-jian.md).

# 第9章 使用预编译的头文件

预编译头文件`(PCH)`是一些编译器支持的一种性能特性，用于编译稳定的代码体，并将代码的编译状态存储在二进制文件中。在后续的编译期间，编译器将加载存储的状态，并继续编译指定的文件。每次后续编译都更快，因为稳定的代码不需要重新编译。

qmake支持在一些平台和构建环境上使用预编译的标头，包括：

* Windows
* nmake
* VisualStudio项目(VS2008及更高版本)
* macOS、iOS、tvOS和watchOS
* Makefile
* Xcode
* Unix
* GCC 3.4及以上
* clang

## 向项目添加预编译头 <a href="#toc20479" id="toc20479"></a>

预编译的标头必须包含在整个项目中都是稳定的和静态的代码。一个典型的预编译的头可能是这样的：

```
// 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
```

<mark style="background-color:yellow;">注：一个预编译的头文件需要分离的C包含和C++包含，因为C文件的预编译的头文件可能不包含C++代码。</mark>

### 项目选项 <a href="#toc28895" id="toc28895"></a>

要使项目使用预编译的头文件，您只需要在项目文件中定义`PRECOMPILED_HEADER`变量：

```
PRECOMPILED_HEADER = stable.h
```

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

针对Windows的`MSVC`和`g++`特性(specs)默认启用`precompile_header`。

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

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

要对`MSVC` nmake目标上的C文件使用预编译头，请将`precompile_header_c`添加到`CONFIG`变量中。如果标头也用于C++，并且它包含C++的关键字`include`，请附上`#ifdef__cplusplus`。

## 关于可能问题的说明 <a href="#toc17867" id="toc17867"></a>

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

```
PRECOMPILED_HEADER = window.h
SOURCES = window.cpp
```

为了避免类似这样的潜在冲突，请为预编译的头文件提供独特的名称。

## 示例项目 <a href="#toc2341" id="toc2341"></a>

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

#### `mydialog.ui` <a href="#toc98" id="toc98"></a>

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

![IMG\_256](/files/1VKJcKh3NSHnshGXpvjn)

### stable.h <a href="#toc4313" id="toc4313"></a>

```
/* Add C includes here */
#if defined __cplusplus
/* Add C++ includes here */
# include <iostream>
# include <QApplication>
# include <QPushButton>
# include <QLabel>
#endif
```

### myobject.h <a href="#toc3779" id="toc3779"></a>

```
#include <QObject>
class MyObject : public QObject
{
public:
MyObject();
~MyObject();
};
```

### myobject.cpp <a href="#toc27642" id="toc27642"></a>

```
#include <iostream>
#include <QDebug>
#include <QObject>
#include "myobject.h"
MyObject::MyObject()
: QObject()
{
std::cout << "MyObject::MyObject()\n";
}
```

### util.cpp <a href="#toc1923" id="toc1923"></a>

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

### main.cpp <a href="#toc15386" id="toc15386"></a>

```
#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 <a href="#toc32115" id="toc32115"></a>

```
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
```
