问题 链接器故障:如何确定“/ DEFAULTLIB”的来源


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

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

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


11934
2018-03-09 17:06


起源



答案:


寻找 #pragma comment(lib) 在源头。看看它是否依赖于a #define  - 这是SDK确保链接正确库的常用方法,您可能需要定义 THESDK_DEBUG 要么 THESDK_RELEASE 为了解决这个问题。

附加信息: 我在Visual Studio 2008中发现甚至可以从* .idl文件中注释掉该语句 不起作用,如:

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

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


5
2018-03-09 17:17





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

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

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

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

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


10
2018-06-03 14:23



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


答案:


寻找 #pragma comment(lib) 在源头。看看它是否依赖于a #define  - 这是SDK确保链接正确库的常用方法,您可能需要定义 THESDK_DEBUG 要么 THESDK_RELEASE 为了解决这个问题。

附加信息: 我在Visual Studio 2008中发现甚至可以从* .idl文件中注释掉该语句 不起作用,如:

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

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


5
2018-03-09 17:17





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

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

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

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

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


10
2018-06-03 14:23



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


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


0
2018-06-30 19:35