1

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

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

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

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

问题:

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

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

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

4

2 回答 2

2

由于某种原因(我是否这样做)编译器生成的 .pdb 文件不是 $(PlatformToolsetVersion).pdb ,而是 $(ProjectName).pdb 。因此,在我的情况下,复制到其他项目文件夹中的共享 .pdb 文件是 pch.pdb,而其他项目需要不同的名称。这触发了 Microsoft.CppCommon.targets 中的 DELETE 任务,(“如果 pdb 文件已被删除,则删除 pch 文件。”)。我没有更改输出 .pdb 名称,而是查看了 XCOPY 命令并将其更改为特定项目所期望的复制文件名(实际上,我只是将带有重命名复制任务的自定义目标添加到项目文件中,而不是使用 CustomBuildStep 调用 xcopy 操作系统的命令,因为现在我了解了有关 MSBuild 的更多信息)。

然后我也改了生成的Linker输出.pdb,只是在名字后面加了“Linked”后缀,这样Compiler的PDB和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>
于 2020-05-11T08:31:57.780 回答
1

你是不是用了github链接下的示例代码。

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

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

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

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

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

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

SharedPCH 项目

在此处输入图像描述

控制台应用程序1

在此处输入图像描述

控制台应用程序2

在此处输入图像描述

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

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

自定义构建步骤在每个项目下--> Properties--> Custom Build Step--> Command Line,然后您就可以找到它。自定义步骤只是CMD命令。你可以在其中执行 CMD 来做额外的操作。

此外,我猜您想制作这些名称xxx.pdbxxx.idb与项目名称相同,以便彼此区分。您可以右键单击每个项目--> Properties--> C/C++--> Output Files--> Program Database File Name-->更改它并使用$(IntDir)$(ProjectName).pdb. 有关自定义构建步骤的更多信息,您可以参考此链接

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

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

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文件,所以在主项目中找不到那些依赖项目的文件。

于 2020-05-08T08:07:31.493 回答