windows - 如何删除警告 LNK4099 : PDB 'lib.pdb' was not found

标签 windows visual-studio visual-studio-2010 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

StackOverflow 给出一个 good overview of the problem ,但不是理解它所需的详细信息。

而不是 ignore the warningdisable the warning ,我想修复构建中的 makefile 以消除问题。

问题是怎么产生的?如何消除警告的原因?

最佳答案

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

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

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

@goth provided a blog link explaining where the .pdb reference comes from ,但这是我的总结:

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

  1. 打开 Visual Studio 命令提示符。这将创建一个命令外壳,其中包含访问 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

...
  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.
  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

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

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

/Fd option governs the name and location of the .pdb symbols file .例如。编译 libcurl 时,我使用了以下标志:

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

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

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

关于windows - 如何删除警告 LNK4099 : PDB 'lib.pdb' was not found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25843883/

相关文章:

C++ - 完全没有 ActiveX 或 MFC 的 Windows Media Player Automation 是否可行?

visual-studio - 如何防止 Visual Studio 创建 "Properties"文件夹?

azure - Visual Studio 2022 - 文件添加新项目 CSS、HTML、JS 缺失

c# - 使用带有引用游标的 Oracle Data Reader

windows - 是否可以运行 Docker Windows 容器并编辑注册表(regedit)?

python - 由于 Web 部署而将绝对路径更改为相对路径(Python - Flask)

c# - Visual Studio 的 Commonclipse?

c++ - 如何通过友元函数调用私有(private)函数?

visual-studio - 在 Visual Studio 中跨项目添加和删除多个引用

c++ - 比较字符串在 mingw 和 ubuntu gcc 上表现不同