42

我有一个包含许多 Visual C++ 项目的解决方案,所有项目都使用 PCH,但有些项目针对特定项目的需要打开了特定的编译器开关。

这些项目中的大多数在各自的 stdafx.h(STL、boost 等)中共享相同的标题集。我想知道是否可以在项目之间共享 PCH,这样我就可以拥有一个解决方案中的大多数项目都可以使用的通用 PCH,而不是为每个项目编译每个 PCH。

似乎可以在项目设置中将 PCH 的位置指定为共享位置,所以我有预感这可以工作。我还假设使用共享 PCH 的所有项目中的所有源文件都必须具有相同的编译器设置,否则编译器会抱怨 PCH 和正在编译的源文件之间的不一致。

有没有人试过这个?它有效吗?

一个相关的问题:这样的分片 PCH 是否应该过度包容,还是会影响整体构建时间?例如,共享 PCH 可能包含许多广泛使用的 STL 标头,但某些项目可能只需要<string><vector>. 当优化器不得不丢弃所有由 PCH 拖入项目的未使用的东西时,使用共享 PCH 节省的时间是否必须在构建过程的稍后阶段归还?

4

6 回答 6

25

是的,这是可能的,我可以向您保证,节省的时间非常可观。编译 PCH 时,必须从创建 PCH 文件的项目中复制.pdb.idb文件。就我而言,我有一个简单的两个文件项目,它正在创建一个 PCH 文件。标头将是您的 PCH 标头,源将被告知在项目设置下创建 PCH - 这类似于您在任何项目中通常会执行的操作。正如您所提到的,您必须为每个配置具有相同的编译设置,否则会出现差异并且编译器会抱怨。

每次重建或每次重新编译 PCH 时都复制上述文件会很痛苦,因此我们将其自动化。要自动复制,请执行预构建事件,将上述文件复制到适当的目录。例如,如果您正在编译DebugRelease构建 PCH,请将 PCH 项目中的文件复制Debug到依赖项目的Debug. 所以复制命令看起来像这样

复制 PchPath\Debug*.pdb Debug\ /-Y

注意/-Y最后。在第一次构建之后,每个后续构建都会增量编译,因此如果再次替换文件,Visual Studio 会抱怨符号损坏。如果它们确实损坏了,您始终可以执行重建,这将再次复制文件(这次它不会跳过它们,因为它们不再存在 - 清理会删除文件)。

我希望这有帮助。我花了很长时间才能够做到这一点,但这是值得的。我有几个项目依赖于一个大框架,PCH 只需要编译一次。现在所有的依赖项目都编译得非常快。

编辑:与其他几个人一起,我在 VS2010 和 VS2012 下对此进行了测试,它似乎确实可以正常工作。

于 2010-11-13T04:05:40.787 回答
16

虽然这是一个老问题,但我想给出一个在 Visual Studio 2017 中有效且不涉及任何复制的新答案。唯一的缺点:编辑和继续不再起作用。

基本上你必须为预编译的头文件创建一个新项目,并让所有其他项目依赖它。这是我所做的:

一步步:

  1. 在您的解决方案中创建一个新项目,其中包括标题(从这里称为 pch.h)和一个包含 pch.h 的单行 cpp 文件。该项目应创建一个静态库。设置新项目以创建预编译头文件。所有项目都需要可以访问输出文件。对我来说,这与 IntDir 相关,但对于默认设置,它可能与 $(SolutionDir) 相关。pch 项目必须只定义所有其他项目也有。

    pch项目设置

  2. 让所有其他项目都依赖于这个新项目。否则构建顺序可能是错误的。

    项目参考

  3. Setup all other projects to use the pch.h. See, how the output file parameters are the same as in the pch project. Additional include directories also need to point to the pch.h directory. Optionally you can force include the pch file in every cpp (or you include it manually in the first line of every cpp file).

    pch 包括 包括

    1. Setup all projects (including the pch project) to use the same compiler symbol file (the linker symbol file is not affected). Again, in my example this is OutDir but in your solution this might vary. It has to point to the same file on disk. The Debug Information Format needs to be set to C7 (see screenshot above), otherwise Visual Studio will not be able to compile projects in parallel. 数据库

I hope I didn't forget anything. For my solution (130k loc, 160 projects) this lead to a compile time of ~2:30mins instead of ~3:30mins.

于 2017-03-13T09:45:53.990 回答
5

这似乎是不可能的,因为每个源文件都必须针对编译 PCH 的同一 PDB 进行编译。该死。

于 2009-03-18T19:14:22.117 回答
5

Samaursa 的回答对我有用。

我还看到了这个有效的链接(在底部附近寻找雷金纳德的答案)。

这个使用copyReginald 的使用xcopy(我更喜欢xcopy)。不管怎样,谢谢——这大大加快了我的构建速度。

于 2010-12-16T18:02:48.777 回答
3

对我来说,这听起来像是一个“收益递减”的案例。假设包含公共头文件直接浪费每个 .cpp 文件 1 秒,并且每个目标(DLL/EXE)有 10 个 .cpp 文件。通过对每个目标使用 .pch,您可以为每个目标节省 10 秒。如果您的整个项目有 10 个目标,则整个构建可以节省 1.5 分钟,这很好。

但是,通过将整个项目的文件减少到一个 .pch,您只能再节省 9 秒。这值得么?额外的工作(设置起来可能要复杂得多,因为 VS 向导不支持非标准配置)只节省了十分之一。

于 2009-03-14T10:52:21.307 回答
1

在 2012 年,您可以使用 PDB 并从仅将 pch 和依赖于 pch lib 的主项目构建到同一目录中的 lib 项目构建 pch(不复制),不幸的是,这不适用于 2013+除了通过冗长的工作-一轮。

于 2019-11-20T12:51:34.460 回答