在Visual Studio中的项目之间共享预编译的标头

时间:2009-03-14 10:39:47

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

我有一个包含许多Visual C ++项目的解决方案,都使用PCH,但有些项目具有特定的编译器开关,以满足项目特定的需求。

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

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

有人试过吗?它有效吗?

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

6 个答案:

答案 0 :(得分:23)

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

每次重建或每次重新编译PCH时复制上述文件都会很麻烦,所以我们会自动完成。要自动执行复制,请执行预构建事件,将上述文件复制到相应的目录。例如,如果您要编译PCH的DebugRelease版本,请将PCH项目的Debug中的文件复制到相关项目的Debug。所以复制命令看起来像这样

  

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

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

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

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

答案 1 :(得分:12)

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

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

一步一步:

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

    pch project settings

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

    project references

  3. 设置所有其他项目以使用pch.h.请参阅输出文件参数与pch项目中的相同内容。其他include目录也需要指向pch.h目录。您可以选择强制在每个cpp中包含pch文件(或者在每个cpp文件的第一行手动包含它)。

    pch include include

    1. 设置所有项目(包括pch项目)以使用相同的编译器符号文件(链接器符号文件不受影响)。同样,在我的示例中,这是OutDir,但在您的解决方案中,这可能会有所不同。它必须指向磁盘上的同一文件。调试信息格式需要设置为C7(参见上面的屏幕截图),否则Visual Studio将无法并行编译项目。 pdb
  4. 我希望我没有忘记任何事情。对于我的解决方案(130k loc,160个项目),这导致编译时间为~2:30分钟而不是~3:30分钟。

答案 2 :(得分:5)

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

答案 3 :(得分:5)

Samaursa的回答对我有用。

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

这个使用copy而雷金纳德使用xcopy(我更喜欢xcopy)。无论哪种方式,谢谢 - 这大大加快了我的构建。

答案 4 :(得分:3)

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

但是通过将整个项目减少到一个.pch,你只需要再节省9秒。这值得么?额外的努力(设置可能更加繁琐,是VS向导不支持的非标准配置)只能节省10%。

答案 5 :(得分:1)

2012年,您可以使用PDB并从仅将pch和依赖于pch lib的主项目构建到同一目录(不复制)的lib项目中构建pch,不幸的是,这不起作用与2013年及以后的版本进行了长期合作。

相关问题