Linker Trouble: How to determine where a “/DEFAULT

2020-08-09 10:15发布

问题:

I am trying to find a good way to determine what module at link time is causing a certain library to get processed as a "/DEFAULTLIB" as seen in the verbose linker output from Visual Studio.

Here is my situation, I have several static library pre-requisites and each has a release and a debug version (BlahD.lib and Blah.lib). For some reason at link time all of the *D.lib's are processed as default libraries even though I am building a release with the non-debug libs specified as "Additional Dependencies". If I never build the debug versions of the static libraries those *D files wouldn't exist and there would be a linker error (can't open file).

I can get my project to build successfully by specifying /NODEFAULTLIB for all of these offending .lib files. All the release libraries link up and everyone is happy. But I want to understand what is going on here. What is causing these *D.lib files to be processed by the linker? Is my only hope to write some kind of script that dumpbins everything in this massive project and its dependant projects (microsoft support)? Even then I don't understand what to look for in the dumpbin output, does this apply to the .lib files as well the .obj files?

回答1:

Look for #pragma comment(lib) in the source. See if it perhaps is dependent on a #define - This is a common way for a SDK to ensure that the right libs are linked, and you may need to define THESDK_DEBUG or THESDK_RELEASE for the logic to work out.

Additional information: I discovered in Visual Studio 2008 that even commenting out the statement from the *.idl file does not work, as in:

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

The compiler still adds MYLIB.lib as a DEFAULTLIB, and it winds up in the *.obj file. Make sure you remove the line completely from the code!



回答2:

I had a similar problem. I was only able to solve it by analyzing the *.obj files as you suggested. To do it, I ran the following command via the Visual Studio command prompt (in the temp folder of the project, where *.obj files are generated):

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

Then I used Notepad++ to search for the name of the offending library in all of these *.directives.txt files. This revealed which project was referencing the wrong lib.

Note: you may want to modify this to include any 3rd-party *.lib files your project may use, and not just *.obj files. "/DEFAULTLIB" directives may also come from them.

Note: you may need to use *.o instead of *.obj



回答3:

Link with the /verbose option and search the output for the name of the library in question. This will tell you which object file dragged the library into the link.