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

Getting started with PCH in a VC++ project

本文关键字:PCH 开始 vc++ 项目      更新时间:2023-10-16

我正在VS 2012中开发一个vc++项目,完整编译大约需要8-10分钟。我知道PCH可以加速编译时间高达10倍。我目前在我的项目中禁用了PCH,我在需要的地方包括头文件。如何开始使用PCH?我到处找"如何做"的指南,但我得到的都是文档。

我想我必须:

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

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

最后但并非最不重要的是,我可以期望使用PCH的编译时间加速是多少?是2 × 10 ×吗?还是会快30% ?

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

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

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

  1. 备份您的src目录和任何其他包含源代码的目录…(万一出了什么问题,你需要这个)

  2. 在你的项目中创建2个文件,Globals.cppGlobals.h ..(选择任何名称,但不要更改)

  3. 右键单击Globals.cpp,打开Properties,选择Configuration>所有配置

  4. 转到C/c++ |预编译头文件,并填写这些内容:

    • 预编译头文件: Create (/Yc)
    • 预编译头文件: global .h
  5. 打开Globals.cpp并添加这一行,没有更多: #include "Globals.h"

  6. 右键单击vc++项目,打开Properties,选择Configuration>所有配置

  7. 转到C/c++ |预编译头文件,并填写这些内容:

    • 预编译头文件: Use (/Yu)
    • 预编译头文件: global .h
  8. 打开项目中的所有.h.cpp文件,并将此添加到最顶部:#include "Globals.h"。如果你不想手动包含每个文件,你可以使用强制包含/FI[name]。

  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文件
  • 删除不使用
  • 的include
  • 浏览你的项目并收集更多的不经常更改的头文件
  • 使用查找和替换,搜索PCH文件中的每个#include,并从项目中的所有.h.cpp文件中删除它们。

  • 做一个完整的编译,并确保一切正常工作。下面是一些你会遇到的常见问题的解决方案:


  • PCH文件包含自身:

    你的PCH文件包含了一个头文件,这个头文件又包含了PCH头文件,这就形成了一种循环依赖。双击错误文件,将您带到有问题的文件,只需删除#include "Globals.h"

    这一行即可。

    未定义符号X

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


    找不到符号logf

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

    1. 右键单击.cpp文件,打开Properties,选择Configuration>所有配置

    2. 转到C/c++ |预编译头文件,并填写这些内容:

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

    4. 添加文件最初导入的内容。(将文件与备份版本进行比较)

    我是这样使用PCH的:

    1. 进入项目属性,C/c++ |PCH设置预编译头选项为'Use'。设置预编译头文件为你想要的东西。
    2. 进入你想要成为PCH的cpp文件的属性,并将预编译头选项设置为"创建"(它将从项目属性设置中默认为"使用")。
    3. 在项目中的所有cpp文件中包含pch头(基本上,那些为预编译头选项设置了'Use'的文件)。我想你可以在项目中关闭一些cpp文件的"使用",而不是添加PCH的包含,但我从来没有尝试过……
    在这一点上,项目应该仍然像以前一样构建和运行,但是在编译时间上可能没有任何真正的改进。现在,您需要将#include "…h"中的一些移动到PCH头文件中(并从项目中的其他地方删除这些文件的include)。应该移动到PCH头文件的include应该是在许多文件中包含的头文件,但是不经常更改。例如:STL头文件,windows.h,项目的核心功能头文件等

    一旦设置了PCH,它应该是透明的。它基本上只是帮助编译器缓存一些中间编译数据。换句话说,如果您在项目中关闭了PCH,那么所有内容的构建都应该与打开PCH时完全一样(除了更慢!)

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