Visual Studio中共享的PCH使用示例

[原文发表地址] Shared PCH usage sample in Visual Studio

[原文作者] EricMittelette

[原文发表时间] 2017/7/5

这篇文章由Olga Arkhipova和Xiang Fan撰写.

通常,Visual Studio解决方案中的多个项目使用相同(或非常相似)的预编译头. 由于pch文件通常很大并且构建它们需要花费大量时间,这就导致了一个共性的问题:几个项目是否可以使用相同的且被构建一次的pch文件?

答案是肯定的,但它需要一些技巧来满足cl的检查,用于构建pch的命令行与使用此pch构建源文件的命令行相同。

这是一个示例解决方案,它有3个项目 - 一个(SharedPCH)正在构建pch和静态库,另外两个(ConsoleApplication 1和2)正在使用它。您可以在我们的VCSamples GitHub存储库中找到示例代码源。

当ConsoleApplication项目引用SharedPCH项目时,构建将自动链接SharedPCH的静态库,但是也需要改变几个项目属性。

  1. C / C ++附加包含目录 (/ I)应包含共享的stdafx.h目录
  2. C / C ++预编译头文件输出文件(/ Fp)应设置为共享pch文件(由SharedPCH项目生成)
  3. 如果您的项目使用/ Zi或/ ZI编译(请参阅最后有关这些开关的更多信息),使用共享pch的项目需要将共享pch项目生成的.pdb和.idb文件复制到其特定位置以便 最终的pdb文件包含pch符号。

由于这些属性需要针对所有项目进行类似的更改,我创建了SharedPCH.props和CustomBuildStep.props文件,并使用Property Manager工具窗口将它们导入到我的项目中。

SharedPch.props帮助#1和#2,并在所有项目中导入。CustomBuildStep.props帮助#3并导入到 重要的pch项目,但不导入生产项目。如果您的项目使用/ Z7,则不需要CustomBuildStep.props。

在SharedPch.props中,我为共享的pch,pdb和idb文件位置定义了属性:

 

我们希望将所有构建输出都放在一个根文件夹下,与源分开,因此我重新定义了输出和中间目录。这对于使用共享pch不是必需的,因为它只是使实验更容易,因为如果出现问题可以删除一个文件夹。

调整后的C / C ++'附加包含目录' 和'预编译头文件输出文件'属性 :

在CustomBuildStep.props中,我定义了自定义构建步骤,以便在ClCompile目标之前运行,并复制共享的pch .pdb和.idb文件(如果它们比项目的.pdb和.idb文件更新)。请注意,我们在这里讨论的是编译器中间pdb文件,而不是链接器生成的最终文件。

如果项目中的所有文件都使用了一个pch,那就是我们需要做的全部,因为当pch被更改时,所有其他文件也需要重新编译,所以在构建结束时我们将拥有完整的pdb和idb文件。

如果您的项目使用多个pch或包含完全不使用pch的文件,则需要更改这些文件的pdb文件位置(/ Fd),以便共享pch pdb不会覆盖它。

我使用命令行属性编辑器来定义命令。每个'xcopy'命令应该在它自己的行上:

或者,您可以将所有命令放在脚本文件中,并将其指定为命令行。

背景资料

/ Z7,/ ZI和/ Zi编译器标志

当使用/ Z7时,调试信息(主要是类型信息)存储在每个OBJ文件中。这包括头文件中的类型,这意味着在共享头文件中存在大量重复,并且OBJ大小可能很大。

使用/ Zi或/ ZI时,调试信息存储在编译器pdb文件中。在一个项目中,源文件通常使用相同的pdb文件(这由/ Fd编译器标志控制,默认值为$(IntDir)vc $(PlatformToolsetVersion).pdb),因此调试信息在它们之间共享。

/ ZI还将生成一个IDB文件来存储与增量编译相关的信息,以支持编辑和继续。

编译器PDB与链接器PDB

如上所述,编译器PDB由/ Zi或/ ZI生成以存储调试信息。稍后,链接器将通过在链接期间组合来自编译器PDB的信息和其他调试信息来生成链接器PDB.链接器还可以删除未引用的调试信息。链接器PDB的名称由/ PDB链接器标志控制。默认值为$(OutDir)$(TargetName).pdb。

给我们您的反馈!

您的反馈是确保我们提供有用信息和功能的关键部分。如有任何问题,请通过@visualc上的Twitter或发送电子邮件至 visualcpp@microsoft.com 与我们联系。如有任何问题或建议,请通过帮助>发送反馈>在IDE中报告问题告诉我们。