【问题标题】:How to remove warning LNK4099: PDB 'lib.pdb' was not found如何删除警告 LNK4099:找不到 PDB 'lib.pdb'
【发布时间】:2014-11-08 17:36:51
【问题描述】:

在静态编译的链接阶段在 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 以消除问题。

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

【问题讨论】:

    标签: windows visual-studio visual-studio-2010 pdb-files


    【解决方案1】:

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

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

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

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

    一个库包含许多目标文件。每个目标文件都包含调试符号的路径。我们可以使用工具提取这些信息。根据目标文件和路径,我们可以找出哪些调试符号文件(.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
    
    ...
    
    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 构建位于同一棵树中。

    【讨论】:

    • 您的回答很棒而且有效!我还有一些问题:如何检查 EXE 或 DLL iso 库所需的 pdb 文件?如果 lib 或 exe 需要多个静态库,您是否应该在对象转储中看到它们各自的 pdb 文件?
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-11
      • 2010-10-11
      • 2012-09-02
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-27
      相关资源
      最近更新 更多