![](/img/trans.png)
[英]MSBuild deletes one lib file, breaking the build. Visual Studio works fine
[英]Visual Studio deletes a shared .pch file, and questions about custom build steps
我尝试使用 shared.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 文件,是否有 RENAME 命令或其他东西,如果复制的 pch.pdb 应该像依赖项目的 PDB 一样命名? 我在哪里可以找到自定义构建步骤命令的完整列表?
3) 我不明白自定义构建步骤中“附加依赖项”和“输出”的用途。 我可以在依赖列表中输入.pch 文件名,这样它就不会被删除吗? output 列表是否需要包含依赖项目的 PDB 名称或 pch.pdb 或两者?
您是否使用了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.pdb
和xxx.idb
与项目名称相同,以便相互区分。 您可以右键单击每个项目 --> Properties
--> C/C++
--> Output Files
--> Program Database File Name
--> 更改它并使用$(IntDir)$(ProjectName).pdb
。 有关自定义构建步骤的更多信息,您可以参考此链接。
我不明白自定义构建步骤中“附加依赖项”和“输出”的目的。 我可以将.pch文件名输入到依赖列表中,这样它就不会被删除? output 列表是否需要包含依赖项目的 PDB 名称或 pch.pdb 或两者?
Additional dependencies
项设置为使用项目 1 和 2 中的 PCH 文件内容,这类似于在 c++ 项目中配置参考 class 库的地址。 而且我认为这可能是多余的,因为作者添加了它,这意味着它是有根据的。
And Outputs is the author customized output path, the author changed the output address of the project, and started a new custom output path and a temporary output path.
实际上,不会将xxx.pch
及其pdb
和idb
文件复制到 outputpath 中。 所以自定义构建步骤是将文件复制到临时 output 路径中。 如果你想将它们复制到最终的输出路径中,你也可以在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>
而事实上,一个工程引用了另一个工程,被引用工程的output文件会自动复制到主工程中。 可能是因为作者的SharePCH项目没有生成pdb和idb文件,所以在主项目中找不到那些依赖项目的文件。
由于某种原因(我是否这样做),compiler.pdb 文件生成的不是 $(PlatformToolsetVersion).pdb,而是 $(ProjectName).pdb。 因此,在我的情况下,复制到其他项目文件夹 shared.pdb 文件是 pch.pdb ,而其他项目期望不同的名称。 这触发了 Microsoft.CppCommon.targets 中的 DELETE 任务,(“如果 pdb 文件已被删除,则删除 pch 文件。”)。 而不是更改 output.pdb 名称,我只是查看了 XCOPY 命令并将复制的文件名更改为特定项目所期望的(实际上,我只是将带有重命名复制任务的自定义目标添加到项目文件中,而不是使用 CustomBuildStep 调用 xcopy 操作系统的命令,因为现在我了解了有关 MSBuild 的更多信息)。
然后我也改了Linker生成的output.pdb,只是在名字后面加了“Linked”后缀,这样编译器和链接器的PDB就没有冲突了。 不确定在没有很大原因的情况下更改默认设置是否是个好主意。
我想最好将编译器的 output PDB 更改为 $(PlatformToolsetVersion).pdb,这样所有项目都将使用相同的名称。
那是我第一次查看 MSBuild 和高级项目设置,现在似乎很明显,使用 shared.pdb 的项目需要一些熟悉的.pdb 名称,而不是随机的 pch.pdb
这是我导入到项目文件中的自定义目标,仅在重新构建时复制 shared.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>
我想补充一点,我遇到过类似的情况,其中 shared.pch 文件被删除,但出于与 .pdb 文件相关的不同原因。
原因是 exe 和 PCH.lib 中的 pdb 格式不同。 PCH 库项目的“项目属性 -> C/C++ -> 常规 -> 调试信息格式”设置为“C7 兼容 (/Z7)”。
当我添加一个依赖于 PCH 库的新项目 exe 时,我忘记了新项目默认使用“程序数据库 (/Zi)”作为其“调试信息格式”。
所以现在当主项目正在构建并与 PCH 链接时,它会删除 PCH.pch 文件并抱怨缺少 .PCH。
让所有项目都具有相同的匹配调试信息格式是防止 PCH 被删除的修复方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.