【问题标题】:Linker Trouble: How to determine where a "/DEFAULTLIB" is coming from链接器问题:如何确定“/DEFAULTLIB”的来源
【发布时间】:2011-07-12 02:08:26
【问题描述】:

我正在尝试找到一种好方法来确定链接时哪个模块导致某个库被处理为“/DEFAULTLIB”,如 Visual Studio 的详细链接器输出所示。

这是我的情况,我有几个静态库先决条件,每个都有一个发布版本和一个调试版本(BlahD.lib 和 Blah.lib)。由于某种原因,在链接时,所有 *D.lib 都作为默认库处理,即使我正在构建一个带有指定为“附加依赖项”的非调试库的版本。如果我从不构建静态库的调试版本,那么这些 *D 文件将不存在,并且会出现链接器错误(无法打开文件)。

我可以通过为所有这些有问题的 .lib 文件指定 /NODEFAULTLIB 来成功构建我的项目。所有的发布库链接起来,每个人都很高兴。但我想了解这里发生了什么。是什么导致链接器处理这些 *D.lib 文件?我唯一的希望是编写某种脚本来转储这个庞大项目及其依赖项目中的所有内容(microsoft support)吗?即使这样,我也不明白要在 dumpbin 输出中查找什么,这是否适用于 .lib 文件以及 .obj 文件?

【问题讨论】:

    标签: c++ visual-studio linker static-libraries


    【解决方案1】:

    我遇到了类似的问题。我只能按照您的建议通过分析 *.obj 文件来解决它。为此,我通过 Visual Studio 命令提示符运行以下命令(在项目的临时文件夹中,其中生成 *.obj 文件):

    for /R %1 in (*.obj) do @dumpbin /directives /section:.drectve "%1" > "%1".directives.txt
    

    然后我使用 Notepad++ 在所有这些 *.directives.txt 文件中搜索有问题的库的名称。这揭示了哪个项目引用了错误的库。

    注意:您可能需要修改它以包含您的项目可能使用的任何第 3 方 *.lib 文件,而不仅仅是 *.obj 文件。 “/DEFAULTLIB”指令也可能来自它们。

    注意:您可能需要使用 *.o 而不是 *.obj

    【讨论】:

    • 如果您的系统支持这些命令,您可以从命令行轻松搜索生成的文件: find 。 -name "*.directives.txt" |xargs grep
    • 我发现这种方法最有用,尽管我发现将所有输出定向到同一个文件更容易,因为我在多个目录中有数百个目标文件。改用 >> c:\directives.txt 重定向。
    • 似乎上述指令以纯文本形式出现在 obj 和 lib 文件中。因此无需调用dumpbin。对我来说,只需从命令行运行以下命令即可:findstr /m /s /c:"/DEFAULTLIB:""mylib *.obj *.lib
    【解决方案2】:

    在源代码中查找#pragma comment(lib)。查看它是否可能依赖于 #define - 这是 SDK 确保链接正确库的常用方法,您可能需要定义 THESDK_DEBUGTHESDK_RELEASE 以实现逻辑。

    附加信息: 我在 Visual Studio 2008 中发现,即使注释掉 *.idl 文件中的语句不起作用,如:

    //cpp_quote("#pragma comment( lib, \"MYLIB.lib\")")
    

    编译器仍将 MYLIB.lib 添加为 DEFAULTLIB,并在 *.obj 文件中结束。确保从代码中完全删除该行!

    【讨论】:

      【解决方案3】:

      使用/verbose 选项链接并在输出中搜索相关库的名称。这将告诉您哪个目标文件将库拖到链接中。

      【讨论】:

        猜你喜欢
        • 2011-03-13
        • 1970-01-01
        • 1970-01-01
        • 2011-08-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-24
        • 1970-01-01
        相关资源
        最近更新 更多