9

我正在 VS 2012 中开发一个 VC++ 项目,完整编译大约需要 8-10 分钟。我知道 PCH 可以将编译时间加快 10 倍。我目前在我的项目中禁用了 PCH,并且在需要的地方包含了头文件。我如何开始使用 PCH?我到处寻找“如何做”指南,但我得到的只是文档。

我假设我必须:

  1. 为PCH配置我的项目,创建一个空白的PCH头文件
  2. 从每个文件中收集头.cpp文件并将其放入 PCH 头文件中
  3. 修改删除所有头文件导入的每个文件
  4. 重新编译并希望不会出错;)

我如何开始使用这个(特别是#1)?您是否修改了项目以使用 PCH,其中的绊脚石或常见问题/问题是什么?PCH 会导致任何问题,还是与正常包含的编译时/运行时行为相同?是否有工具可以自动化该过程,还是我必须手动浏览 500 个 .cpp 文件并对其进行修改以使用 PCH?

最后但并非最不重要的一点是,我可以期望 PCH 的编译时间加速是多少?是2x-10x吗?还是会快 30%?(这不能证明所涉及的时间是合理的)

4

2 回答 2

9

在将我的项目配置为使用 PCH 后,完整编译时间减少了一半,增量构建几乎立即发生。PCH 是一种非常有效的加速编译时间的方法,我强烈推荐它。

尽管 dsharlet提到了许多重要点,但他跳过了一些我最终必须弄清楚的关键步骤。因此,这里是配置项目以使用 PCH 的完整指南:

在 VC++ 项目中开始使用 PCH

  1. 备份您的src目录和任何其他包含源代码的目录......(如果出现任何问题,您将需要这个)

  2. 在您的项目中创建 2 个文件,Globals.cpp然后Globals.h..(选择任何名称但坚持使用)

  3. 右键单击Globals.cpp并打开Properties,选择 Configuration > All configuration

  4. 转到 C/C++ | 预编译的Header,并填写:

    • 预编译头文件:创建 (/Yc)
    • 预编译头文件:Globals.h
  5. 打开Globals.cpp并添加这一行,仅此而已#include "Globals.h"

  6. 右键单击您的 VC++ 项目并打开Properties,选择 Configuration > All configurations

  7. 转到 C/C++ | 预编译的Header,并填写:

    • 预编译头文件:使用 (/Yu)
    • 预编译头文件:Globals.h
  8. 打开项目中的所有.h.cpp文件,并将其添加到最顶部: #include "Globals.h"

  9. 打开Globals.h并添加以下内容:(它#pragma once在顶部非常重要)

     #pragma once
    
     #include <stdio.h>
     #include <stdlib.h>
     #include <stdarg.h>
     #include <stddef.h>
     #include <memory>
     #include <string.h>
     #include <limits.h>
     #include <float.h>
     #include <time.h>
     #include <ctype.h>
     #include <wchar.h>
     #include <wctype.h>
     #include <malloc.h>
     #include <locale.h>
     #include <math.h>
    
     // Windows SDK
     #define _WIN32_WINNT 0x0501     // _WIN32_WINNT_WINXP
     #include <SDKDDKVer.h>
    
     // Windows API
     #define WIN32_LEAN_AND_MEAN
     #include <windows.h>
    
    • 这些包括是您的 PCH 文件的典型候选者
    • 删除您不使用的包含
    • 浏览您的项目并收集更多不经常更改的头文件
  10. 使用查找和替换,在 PCH 文件中搜索每个#include',然后从项目中的所有.h.cpp文件中删除它们。

  11. 进行完整编译并确保一切正常。以下是您将遇到的常见问题的一些解决方案:


PCH 文件包括自身:

您的 PCH 文件包含一个包含 PCH 头文件的头,从而创建了一种循环依赖。双击错误将您带到有问题的文件,然后只需删除显示的行#include "Globals.h"


未定义符号 X

虽然你所有的项目文件都可以包含 PCH 头文件,但是包含PCH 头文件中的文件不能包含 PCH 头文件!(如上所述),因此您需要重新添加之前在文件中的所有导入。(将文件与备份版本进行比较)


找不到符号 logf

有时,全局 PCH 文件的行为不符合预期,并且会因无法解决的疯狂错误而中断编译。然后,您可以关闭单个源代码文件的 PCH。

  1. 右键单击您的.cpp文件并打开Properties,选择 Configuration > All configurations

  2. 转到 C/C++ | 预编译的Header,并填写:

    • 预编译头文件:不使用预编译头文件
  3. 删除文件#include "Globals.h"中的行.cpp

  4. 重新添加文件最初具有的任何导入。(将文件与备份版本进行比较)

于 2013-05-25T06:07:31.200 回答
1

以下是我使用 PCH 获得不错结果的方法:

  1. 转到项目属性,C/C++|PCH 将 Precompiled Header 选项设置为“Use”。将 Precompiled Header File 设置为您想要的内容。
  2. 转到您想成为 PCH 的 cpp 文件的属性,并将 Precompiled Header 选项设置为“创建”(它在项目属性设置中默认为“使用”)。
  3. 在项目的所有 cpp 文件中包含 pch 头文件(基本上,那些为 Precompiled Header 选项设置了“使用”的文件)。我想您可以为项目中的某些 cpp 文件关闭“使用”,而不是为 PCH 添加包含,但我从未尝试过...

在这一点上,项目应该仍然像以前一样构建和运行,但编译时间可能没有任何真正的改进。现在,您需要将一些#include "...h" 移动到 PCH 头文件(并从项目的其他位置删除这些文件的包含)。您应该移动到 PCH 标头的包含应该是许多文件中包含的标头,但很少更改。示例:STL 头文件、windows.h、项目中的核心功能头文件等。

一旦 PCH 建立,它应该是透明的。它基本上只是帮助编译器缓存一些中间编译数据。换句话说,如果你在你的项目中关闭了 PCH,所有的东西都应该和打开 PCH 的时候完全一样(除了更慢!)

加速完全取决于将多少代码移动到 PCH 中(有多少头文件中包含的代码从任意 cpp 文件移动到 PCH 头文件)。我已经看到了多次改进,但没有精确地对其进行基准测试。当我在一个大项目中使用 PCH 遇到麻烦时,我绝对觉得这样做是值得的。

于 2013-05-23T07:11:24.310 回答