我有一个包含许多Visual C++项目的解决方案,所有这些项目都使用PCH,但有些项目具有特定的编译器开关以满足项目特定的需求.
大多数这些项目在各自的stdafx.h(STL,boost等)中共享相同的头文件集.我想知道是否可以在项目之间共享PCH,这样我就可以拥有一个普通的PCH而不是编译每个项目的PCH,解决方案中的大多数项目都可以使用.
似乎可以将PCH的位置指定为项目设置中的共享位置,因此我有预感这可行.我还假设所有使用共享PCH的项目中的所有源文件都必须具有相同的编译器设置,否则编译器会抱怨PCH与正在编译的源文件之间的不一致.
有没人试过这个?它有用吗?
一个相关的问题:这样的碎片PCH应该过于包容,还是会损害整体构建时间?例如,共享PCH可能包含许多广泛使用的STL标头,但某些项目可能只需要
和
.当优化器必须丢弃由PCH拖入项目的所有未使用的东西时,使用共享PCH节省的时间是否必须在构建过程的稍后时间回收?
是的,这是可能的,我可以向您保证,节省的时间非常重要.编译PCH时,必须从创建PCH文件的项目中复制.pdb
和.idb
文件.在我的例子中,我有一个简单的两个文件项目,即创建一个PCH文件.标题将是您的PCH标题,并且将告知源代码在项目设置下创建PCH - 这类似于您在任何项目中通常所做的操作.正如您所提到的,您必须为每个配置设置相同的编译设置,否则会出现差异并且编译器会抱怨.
每次重建或每次重新编译PCH时复制上述文件都会很麻烦,所以我们会自动化它.要自动执行复制,请执行预构建事件,将上述文件复制到相应的目录.例如,如果您正在编译Debug
和Release
构建PCH,Debug
请将PCH项目中的文件复制到相关项目中Debug
.所以复制命令看起来像这样
复制PchPath\Debug*.pdb Debug\/ -Y
注意/-Y
最后.在第一次构建之后,每个后续构建都是逐步编译的,因此如果再次替换文件,Visual Studio会抱怨已损坏的符号.如果它们确实被破坏,您可以随时执行重建,这将再次复制文件(这次它不会跳过它们,因为它们不再存在 - 清理会删除文件).
我希望这有帮助.我花了很长时间才能做到这一点,但这是值得的.我有几个依赖于一个大框架的项目,而PCH只需要编译一次.所有依赖项目现在编译得非常快.
编辑:与其他几个人一起,我已经在VS2010和VS2012下进行了测试,看起来它确实运行正常.
虽然这是一个老问题,但我想给出一个在Visual Studio 2017中有效且不涉及任何复制的新答案.唯一的缺点:编辑和继续不再起作用.
基本上,您必须为预编译的头创建一个新项目,并让所有其他项目依赖它.这是我做的:
一步步:
在您的解决方案中创建一个新项目,其中包括标题(从此处称为pch.h)和包含pch.h的单行cpp文件.该项目应该创建一个静态库.设置新项目以创建预编译头.所有项目都需要可以访问输出文件.对我来说这相对于IntDir,但对于默认设置,它可能相对于$(SolutionDir).pch项目必须只定义所有其他项目.
所有其他项目都依赖于这个新项目.否则,构建顺序可能是错误的.
设置所有其他项目以使用pch.h. 请参阅输出文件参数与pch项目中的相同内容.其他include目录也需要指向pch.h目录.您可以选择强制在每个cpp中包含pch文件(或者在每个cpp文件的第一行手动包含它).
设置所有项目(包括pch项目)以使用相同的编译器符号文件(链接器符号文件不受影响).同样,在我的示例中,这是OutDir,但在您的解决方案中,这可能会有所不同.它必须指向磁盘上的同一文件.调试信息格式需要设置为C7(参见上面的屏幕截图),否则Visual Studio将无法并行编译项目.
我希望我没有忘记任何事情.对于我的解决方案(130k loc,160个项目),这导致编译时间为~2:30分钟而不是~3:30分钟.
这似乎是因为每个源文件必须对针对其PCH编译相同PDB编译这是不可能的.弄它.
Samaursa的回答对我有用.
我也看到了这个有用的链接(在底部附近寻找雷金纳德的答案).
这个使用copy
Reginald的用途xcopy
(我更喜欢xcopy
).无论哪种方式,谢谢 - 这大大加快了我的构建.