如何删除警告LNK4099:找不到PDB'lib.pdb'

Don*_*rty 21 windows visual-studio-2010 visual-studio pdb-files

在静态编译的链接阶段在Windows上构建时,可能会发生LNK4099警告.

例如,当使用nmake和VC10构建时,我得到一个LNK4099警告流,如:

libcurl_a_debug.lib(rc2_cbc.obj) : warning LNK4099: PDB 'lib.pdb' was not found with 'libcurl_a_debug.lib(rc2_cbc.obj)' or at 'C:\dev\scaler\center\dlux\lib.pdb'; linking object as if no debug info
Run Code Online (Sandbox Code Playgroud)

StackOverflow可以很好地概述问题,但不是理解它所需的详细信息.

而不是忽略警告禁用警告,我想修复我的构建中的makefile以解决问题.

问题是怎么出现的?如何删除警告的原因?

Don*_*rty 39

了解基础问题是警告中提到的库缺少调试符号文件(.pdb).库文件包含基于目标文件的.pdb静态引用.当另一个库使用库并使用静态编译时,Visual Studio会将所有符号收集到一个.pdb中,并更新目标文件中的.pdb引用.但是,如果找不到符号,它将保留旧路径.

通过重新编译警告中提到的库来修复警告,并确保编译器可以访问每个引用库的.pdb.这涉及确定无法找到哪个.pdb文件,然后进行更改以确保找到.pdb.

哪个目标文件(以及库)我们缺少符号(.pdb)?

@goth 提供了一个博客链接,解释了.pdb引用的来源,但这是我的总结:

库包含许多目标文件.每个目标文件都包含调试符号的路径.我们可以使用工具提取这些信息.根据目标文件和路径,我们可以确定找不到哪个调试符号文件(.pdb).

  1. 打开Visual Studio命令提示符.这将创建一个命令shell,其中包含访问Visual Studio工具所需的环境变量.(应该在"开始菜单"中隐藏的"Visual Studio工具"下,但这会有所不同)

  2. 使用lib工具/list选项获取库中目标文件的内部路径.例如

C:\dev\libcurl\win\lib>lib /list libcurl_a_debug.lib > list_of_object_files_in_library.txt

C:\dev\scaler\center\agent\thirdparty\libcurl\win\lib>more list_of_object_files_in_library.txt
Microsoft (R) Library Manager Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

..\builds\libcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/file.obj
..\builds\libcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/timeval.obj
..\builds\libcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/rc2_cbc.obj

...
Run Code Online (Sandbox Code Playgroud)
  1. 使用该路径,使用lib工具/extract选项提取目标文件.
C:\dev\scaler\center\agent\thirdparty\libcurl\win\lib>lib /extract:..\builds\libcurl-vc10-x86-debug-static-ssl-static-ipv6-spnego-obj-lib/timeval.obj libcurl_a_debug.lib
Microsoft (R) Library Manager Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.
Run Code Online (Sandbox Code Playgroud)
  1. 目标文件包含一个调用部分.debug$T,我们可以使用该dumpbin工具提取该部分.例如
C:\dev\scaler\center\agent\thirdparty\libcurl\win\lib>dumpbin /section:.debug$T /rawdata rc2_cbc.obj > dump_of_object_file_debug_info.txt

C:\dev\scaler\center\agent\thirdparty\libcurl\win\lib>more dump_of_object_file_debug_info.txt
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file ./rc2_cbc.obj

File Type: COFF OBJECT

SECTION HEADER #9
.debug$T name
       0 physical address
       0 virtual address
      5C size of raw data
    1D53 file pointer to raw data (00001D53 to 00001DAE)
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
42100040 flags
         Initialized Data
         Discardable
         1 byte align
         Read Only

RAW DATA #9
  00000000: 04 00 00 00 56 00 15 15 03 7A 47 A3 3D 4A 8C 4B  ....V....zGú=J.K
  00000010: A2 A5 26 D3 D6 57 15 46 3A 00 00 00 73 3A 5C 73  óÑ&ËÍW.F:...s:\s
  00000020: 63 61 6C 65 78 2E 6E 65 77 5C 63 65 6E 74 72 6F  caler.new\center
  00000030: 5C 6F 70 65 6E 73 73 6C 5C 62 75 69 6C 64 5C 6F  \openssl\build\o
  00000040: 70 65 6E 73 73 6C 2D 31 2E 30 2E 30 62 5C 74 6D  penssl-1.0.0b\tm
  00000050: 70 33 32 5C 6C 69 62 2E 70 64 62 00              p32\lib.pdb.

  Summary

          5C .debug$T
Run Code Online (Sandbox Code Playgroud)

在上面,您会看到目标文件显示其调试符号s:\scaler.new\center\openssl\build\openssl-1.0.0b\tmp32\lib.pdb.因此,问题在于我们构建libcurl使用的openssl库时生成的.pdb.

如何将调试符号添加到生成警告的库中?

/依存选项支配的.pdb符号文件的名称和位置.例如,在编译libcurl时,我使用了以下标志:

...
!IF DEFINED(VC10)
NT_MAK_FLAGS = APP_CFLAG="/GX /GZ /MTd /Fdtmp32.dbg/app" LIB_CFLAG="/Zl /Z7 /Fdtmp32.dbg/lib"
!ENDIF
...
Run Code Online (Sandbox Code Playgroud)

符号文件名lib.pdb及其相对于构建的路径由下式给出/Fdtmp32.dbg/lib.

问题是,它NT_MAK_FLAGS被重用于编译openssl时生成的许多库.结果,lib.pdb除了最后一个库之外的所有文件都被破坏(覆盖).要解决此问题,应为每个库提供唯一名称的.pdb.要进一步简化问题,请确保编译位置与libcurl构建位于同一树中.


Owe*_*sen 12

这发生在我身上的库.lib,也许附加的图像会帮助其他人.在我的情况下,我必须确保.lib和.pdb文件位于同一目录中,因此请注意$(OutDir)在设置中的显示方式.

确保目录相同

当我将一个旧的32位VS2010项目导入VS2013并将其设置为64位时,我认为它们未对齐.

所以我最终得到了这个(好的)情况:

.lib和.pdb在同一目录中