移动静态库的 *.pdb 文件而不破坏引用 - LNK4099

Move *.pdb file for static library without breaking references - LNK4099

我在名为 <libraryBuildDir> 的文件夹中构建了一个第 3 方静态库,并将生成的 *.lib 文件复制到我的项目文件夹结构中。除了 *.lib,我还放置了 *.pdb 文件。然后我删除了 <libraryBuildDir>,假设它不再需要了。这是之前对其他库有效的方法,它遵循 what seems to be a common practice.

然而,当我在调试配置中构建我的项目时,我收到许多这样的 LNK4099 警告(粗略翻译):

<myLib>.lib(<someObjFromTheLib>.obj) : warning LNK4099: PDB "<myLib>.pdb" was not found alongside "<myLib.lib>" or "<myBuildDir>". Linking without debug info

我确认 *.pdb 文件就在 *.lib 文件旁边。 作为测试,我按照警告的建议将其直接放入构建目录中。现在我得到了很多这样的 LNK4204:

<myLib>.lib(<someObjFromTheLib>.obj) : warning LNK4204: "<myBuildDir>\<myLib>.pdb" is missing debugging information for referencing module; linking object as if no debug info

我按照 this advice 提取了出现在我的警告中的目标文件之一,(<someObjFromTheLib>.obj)。我注意到提取的 *.obj 文件不包含 Debug$T 部分。

显然,当我将 *.pdb 文件从 <libraryBuildDir> 复制到我的项目时,我破坏了一些指向其他调试符号文件的链接,这些文件现在不再可用,因为我删除了 <libraryBuildDir>。这让我觉得我的整个过程都是错误的。

我的目标:编译带有调试符号的静态库,并将完成的*lib文件移动到另一个项目。然后编译另一个项目并包含静态库中的完整调试符号。

如何在不破坏任何引用的情况下将 pdb 文件从临时库构建目录移动到另一个目录?

(旁注:我正在使用 cmake 编译 Crypto++ v8.2.0,*.pdb 文件称为 cryptopp-object.pdb,而库称为 cryptopp-static.lib。这违反了 *.pdb 文件的约定。 lib 和 *.pdb 具有相同的名称,但它是 Crypto++ 的配置方式,我不想尽可能更改它。但是,*.lib 文件似乎期望其 pdb 文件的名称正确,所以我假设这很好。)

(另外:lib /list <myLib>.lib 列出了很多 *.obj 文件,其中只有一些出现在我的 LNK4099 警告中,而其他的则没有。我不知道这是否意味着它们只是未在我的项目中使用,或者如果他们有所有可用的调试信息。)

解决方案:构建不是确定性的。 *.pdb 和 *.lib 文件必须来自完全相同的 "build".

Turns out, If I recompile and copy the lib and pdb from the exact same run, the problem seems to disappear.

Why on earth are the results not deterministic?

a) 因为 PDB 包含一个时间戳,并且该时间戳在不同的构建中很少会相同

b) 因为现在构建可以是多线程的,因此会导致不同的结果,这取决于首先编译的是什么。

c) "same" 代码(关于行为)可以产生不同的 AST,例如如果您只是移动方法。

How can I move a pdb file from a temporary library build directory to another directory without breaking any references?

只要 PDB 与构建匹配,就应该可以。但是,考虑构建到所需的目录 using the /Fd option for the PDB and /Fo option for the OBJ.