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

时间:2013-05-23 06:30:50

标签: c++ visual-c++ compilation precompiled-headers

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

我假设我必须:

  1. 为PCH配置我的项目,创建一个空白的PCH头文件
  2. 从每个.cpp文件中收集标头并将其放入PCH标头文件
  3. 修改删除所有标头导入的每个文件
  4. 重新编译并希望没有出错;)
  5. 我如何开始这个(特别是#1)?您是否修改了使用PCH的项目以及其中的绊脚石或常见问题/问题? PCH会导致任何问题,还是与正常包含的编译时/运行时行为相同?是否有自动化过程的工具,或者我必须手动通过500个.cpp文件并修改它以使用PCH?

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

2 个答案:

答案 0 :(得分:8)

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

Althouh dsharlet提到了很多重要的观点,他跳过了我最终要弄清楚的一些关键步骤。以下是配置项目以使用PCH的完整指南:

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

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

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

  3. 右键点击Globals.cpp并打开属性,然后选择配置> 所有配置

  4. 转到C / C ++ |预编译的标题,并填写以下内容:

    • 预编译标题:创建(/ Yc)
    • 预编译的头文件:Globals.h
  5. 打开Globals.cpp并添加以下一行 #include "Globals.h"

  6. 右键单击您的VC ++项目并打开属性,然后选择配置> 所有配置

  7. 转到C / C ++ |预编译的标题,并填写以下内容:

    • 预编译标题:使用(/ 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. 进行完整编译并确保一切正常。以下是您将遇到的常见问题的一些解决方案:


  12. PCH文件包括:

    您的PCH文件包含一个标题,该标题再次包含PCH头文件,从而创建一种循环依赖关系。双击错误将您带到违规文件,只需删除显示#include "Globals.h"

    的行

    未定义的符号X

    虽然所有项目文件都可以包含PCH标题,但 PCH标题中包含的文件不能包含PCH标题! (如上所述)所以你需要添加以前在文件中的任何导入。 (使用备份版本区分文件)


    无法找到符号logf

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

    1. 右键单击您的.cpp文件并打开属性,然后选择配置&gt; 所有配置

    2. 转到C / C ++ |预编译的标题,并填写以下内容:

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

    4. 添加原始文件的任何导入。 (使用备份版本区分文件)

答案 1 :(得分:1)

以下是我如何使用PCH获得不错的结果:

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

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

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