Visual Studio 删除一个共享的 .pch 文件,以及关于自定义构建步骤的问题

Visual Studio deletes a shared .pch file, and questions about custom build steps

我尝试使用一个共享的.pch文件,在一个项目中编译,在其他项目中使用。

但是,如果 PCH 项目的 .pdb 文件名与其他项目的 .pdb 文件名不同,则会删除 .pch 文件。

此页面没有回答问题:https://devblogs.microsoft.com/cppblog/shared-pch-usage-sample-in-visual-studio/

我不想对所有 PDB 使用相同的名称。

问题:

1)为什么.pch文件在其他项目编译开始时被删除,导致C1083错误(找不到.pch),如果PDB名称不相等,不像那个页面?

2) 我使用 COPY 命令复制 pch.pdb 和 pch.idb 文件,是否有重命名命令或其他东西,如果复制的 pch.pdb 应该像依赖项目的 PDB 一样命名?我在哪里可以找到自定义生成步骤命令的完整列表?

3) 我不明白自定义构建步骤中 "Additional dependencies" 和 "Outputs" 的用途。我可以将 .pch 文件名输入到依赖列表中,这样它就不会被删除吗?输出列表是否需要包含依赖项目的 PDB 名称或 pch.pdb,或两者都包含?

您是否使用了github link下的示例代码。

如果是这样,您应该下载并使用该示例,如果您创建自己的项目,您应该仔细检查您的项目。

借用本教程到你的项目,我认为你需要注意你的 xxx.vcxproj 文件中是否有任何额外的自定义目标删除 PCH文件。因此,您需要仔细检查每个 xxx.vcxproj 文件。在vs中,由于PCH工程和其他工程的.pdb文件名不同,会出现某些文件没有删除的情况,所以请检查是否有自己的额外操作。

1) Why the .pch file is deleted at the start of other projects compilation, which leads to a C1083 error (.pch not found), if PDB names are not equal, not like in that page?

首先,请确保您的项目中没有其他选项可以删除 PCH 文件。

PCH项目是创建一个PCH文件,另外两个项目是使用这个文件。每次构建两个项目时(引用 PCH 项目),总是执行 PCH 项目的构建,然后构建两个项目。所以 PCH 总是被创建,然后在两个项目中使用。

基于,你应该确保所有三个项目创建和使用相同的文件地址。

SharedPCH 项目

ConsoleApplication1

ConsoleApplication2

在示例代码中,PCH 文件存在于 SharedPchSample\Outputs\Intermediate\Shared\Win32\Debug.

2) I copy pch.pdb and pch.idb files using COPY command, is there a RENAME comand or something, if the copied pch.pdb should be named just like a dependent project's PDB? And where can I find a complete list of Custom Build Step command?

Custom Build Step在每个项目下-->Properties-->Custom Build Step-->Command Line,然后你可以发现 it.That 自定义步骤只是 CMD 命令。你可以在里面执行CMD来做额外的操作。

除了,我猜你想让那些xxx.pdbxxx.idb与项目名称相同,以便彼此区分.您可以右键单击每个项目-->Properties-->C/C++-->Output Files-->Program Database File Name-->更改它并使用$(IntDir)$(ProjectName).pdb。更多关于自定义构建步骤,您可以参考this link

I don't understand the purpose of "Additional dependencies" and "Outputs" in Custom Build Step. Can I enter the .pch filename into the dependency list, so it won't be deleted? Does the output list need to contain the dependent project's PDB name, or the pch.pdb, or both?

Additional dependencies设置为在项目1和2中使用PCH文件的内容,这类似于在c++项目中配置引用class库的地址。而且我认为它可能是多余的,因为作者添加了它,这意味着它是有根据的。

Outputs是作者自定义的输出路径,作者更改了项目的输出地址,并启动了新的自定义输出路径和临时输出路径。

实际上xxx.pch 及其 pdbidb 文件不会被复制到输出路径中。所以自定义构建步骤是将文件复制到临时输出路径。如果你想将它们复制到最终的输出路径中,你也可以在 CustomBuildStep.targets 文件中使用它们:

<CustomBuildStep>
<Command>
if EXIST "$(SharedPdb)" xcopy /Y /F "$(SharedPdb)" "$(IntDir)"
if EXIST "$(SharedIdb)" xcopy /Y /F "$(SharedIdb)" "$(IntDir)"
if EXIST "$(SharedPdb)" xcopy /Y /F "$(SharedPdb)" "$(OutDir)"
if EXIST "$(SharedIdb)" xcopy /Y /F "$(SharedIdb)" "$(OutDir)"
</Command>
<Outputs>$(IntDir)vc$(PlatformToolsetVersion).pdb;</Outputs>
<Inputs>$(SharedPdb)</Inputs>
</CustomBuildStep>

实际上,一个项目引用了另一个项目,引用项目的输出文件会自动复制到主项目中。可能是因为作者的SharePCH工程没有生成pdb和idb文件,所以在主工程中是找不到依赖工程的那些文件的。

出于某种原因(我是否这样做),编译器生成的 .pdb 文件不是 $(PlatformToolsetVersion).pdb,而是 $(ProjectName).pdb。因此,在我的例子中,复制到其他项目文件夹中的共享 .pdb 文件是 pch.pdb,而其他项目则需要不同的名称。这在 Microsoft.CppCommon.targets 中触发了一个 DELETE 任务,("Delete the pch file if the pdb file has been deleted.")。我没有更改输出 .pdb 名称,而是查看了 XCOPY 命令并将复制的文件名更改为特定项目所期望的名称(实际上我只是将带有重命名复制任务的自定义目标直接添加到项目文件中而不是使用 CustomBuildStep 调用 xcopy OS 的命令,因为现在我了解了有关 MSBuild 的更多信息。

然后我也更改了Linker输出生成的.pdb,只是在名称中添加了"Linked"后缀,因此Compiler和Linker的PDB之间没有冲突。不确定在没有重大原因的情况下更改默认设置是否是个好主意。

我想最好将编译器的输出 PDB 更改为 $(PlatformToolsetVersion).pdb ,这样所有项目都将使用相同的名称。

那是我第一次研究 MSBuild 和高级项目设置,现在看来很明显,使用共享 .pdb 的项目需要一些熟悉的 .pdb 名称,而不是随机 pch.pdb

这是我导入到项目文件中的自定义目标,仅当它被重建时才复制共享的 .pdb(在我的情况下未生成 .idb):

<Target Name="CopyFreshPchPdb" BeforeTargets="ClCompile" 
    Inputs="$(PchDir)\pch.pdb"
    Outputs="$(IntDir)$(ProjectName).pdb">
    <Message  Importance="High" Text="Copying shared pch.pdb" />
    <Copy
        SourceFiles="$(PchDir)\pch.pdb"
        DestinationFiles="$(IntDir)$(ProjectName).pdb">
    </Copy>
</Target>