在vc++项目中开始使用PCH
Getting started with PCH in a VC++ project
我正在VS 2012中开发一个vc++项目,完整编译大约需要8-10分钟。我知道PCH可以加速编译时间高达10倍。我目前在我的项目中禁用了PCH,我在需要的地方包括头文件。如何开始使用PCH?我到处找"如何做"的指南,但我得到的都是文档。
我想我必须:
- 配置我的PCH项目,创建一个空白的PCH头文件
- 收集每个
.cpp
文件的头文件,并将其放入PCH头文件 - 修改每个文件,删除所有头文件导入
- 重新编译,希望不会出错;)
我如何开始这个(特别是#1)?您是否曾修改项目以使用PCH ?其中的绊脚石或常见问题是什么?PCH是否会导致任何问题,或者它只是与正常包含相同的编译时/运行时行为?是否有工具可以自动执行该过程,或者我必须手动遍历500个.cpp文件并修改它以使用PCH?
最后但并非最不重要的是,我可以期望使用PCH的编译时间加速是多少?是2 × 10 ×吗?还是会快30% ?
在将我的项目配置为使用PCH之后,完整编译时间减少了一半,增量构建几乎立即发生。PCH是一种非常有效的加速编译时间的方法,我强烈推荐它。
尽管dsharlet提到了许多重要的点,但他省略了一些我最终必须弄清楚的关键步骤。下面是配置项目以使用PCH的完整指南:
在vc++项目中开始使用PCH
-
备份您的
src
目录和任何其他包含源代码的目录…(万一出了什么问题,你需要这个) -
在你的项目中创建2个文件,
Globals.cpp
和Globals.h
..(选择任何名称,但不要更改) -
右键单击
Globals.cpp
,打开Properties,选择Configuration>所有配置 -
转到C/c++ |预编译头文件,并填写这些内容:
- 预编译头文件: Create (/Yc)
- 预编译头文件: global .h
-
打开
Globals.cpp
并添加这一行,没有更多:#include "Globals.h"
-
右键单击vc++项目,打开Properties,选择Configuration>所有配置
-
转到C/c++ |预编译头文件,并填写这些内容:
- 预编译头文件: Use (/Yu)
- 预编译头文件: global .h
-
打开项目中的所有
.h
和.cpp
文件,并将此添加到最顶部:#include "Globals.h"
。如果你不想手动包含每个文件,你可以使用强制包含/FI[name]。 -
打开
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
文件中删除它们。 -
做一个完整的编译,并确保一切正常工作。下面是一些你会遇到的常见问题的解决方案:
右键单击
.cpp
文件,打开Properties,选择Configuration>所有配置转到C/c++ |预编译头文件,并填写这些内容:
- 预编译头文件:不使用预编译头文件
删除
.cpp
文件中的#include "Globals.h"
行添加文件最初导入的内容。(将文件与备份版本进行比较)
PCH文件包含自身:
你的PCH文件包含了一个头文件,这个头文件又包含了PCH头文件,这就形成了一种循环依赖。双击错误文件,将您带到有问题的文件,只需删除#include "Globals.h"
未定义符号X
虽然您的所有项目文件都可以包含PCH头,但PCH头中包含的文件不能包含PCH头!(如上所述),因此您需要重新添加之前在文件中的任何导入。(将文件与备份版本进行比较)
找不到符号logf
有时全局PCH文件的行为不像预期的那样,并且由于无法解决的疯狂错误而中断编译。然后,您可以为单个源代码文件关闭PCH。
我是这样使用PCH的:
- 进入项目属性,C/c++ |PCH设置预编译头选项为'Use'。设置预编译头文件为你想要的东西。
- 进入你想要成为PCH的cpp文件的属性,并将预编译头选项设置为"创建"(它将从项目属性设置中默认为"使用")。
- 在项目中的所有cpp文件中包含pch头(基本上,那些为预编译头选项设置了'Use'的文件)。我想你可以在项目中关闭一些cpp文件的"使用",而不是添加PCH的包含,但我从来没有尝试过……
一旦设置了PCH,它应该是透明的。它基本上只是帮助编译器缓存一些中间编译数据。换句话说,如果您在项目中关闭了PCH,那么所有内容的构建都应该与打开PCH时完全一样(除了更慢!)
加速完全取决于有多少代码被移动到PCH中(有多少包含在头文件中的代码从任意cpp文件移动到PCH头文件中)。我已经看到了多次改进,但还没有进行精确的基准测试。当我经历了在一个大项目中使用PCH的麻烦时,我绝对觉得这是值得做的。
- 当回溯以零开始时,如何调试崩溃
- 根据用户输入用字母填充矢量,并将"开始"和"结束"放在四肢
- 如何从头开始创建 avi 文件?
- 为什么 -mmacosx-version-min=10.10 不阻止使用标记为从 10.11 开始的函数?
- 自一周开始以来的秒数?
- 一旦双簧管录制开始,主 UI 线程就会被阻止
- GStreamer在开始任何播放之前进行搜索
- 使 std::fstream 写入文件末尾,但从头开始读取
- 如何以毫秒为单位获取开始时间和 now() 之间的毫秒差异(以 C++为单位?
- 哪个C++规范开始支持 std::vector
- 如何继续读取不同功能中的文件,而不是从头开始再次读取文件?
- 如何在 c++ 中确定一条指令(以字节为单位)在哪里结束,另一条指令从哪里开始?
- 如何在调试中通过传递引用开始
- 如何使用 picojson.h 在 c++ 中从头开始创建 json 对象
- 从特定键开始遍历地图
- 列表的有效性在插入后开始迭代器
- 尝试从头开始实现Leetcode的FizzBuzz多线程问题。收到"libc++abi.dylib: terminating"错误
- 试图修复一个错误,该错误不会让我开始编程其余部分
- 甚至在开始执行之前出现分段错误
- 在vc++项目中开始使用PCH