I am now, unfortunately, an expert in how Microsoft Visual C++ links in and embeds library information. This is really a continuation of the issues I was having yesterday. Basically, it boils down to dealing with linker warnings such as:
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
And while the first one is a warning, I’ve found that the resultant binary will crash. By using the
depends.exe tool (which is also available separately from Visual Studio) to walk DLL dependencies, you can see both the debug (MSVC71D.DLL) and non-debug (MSVC71.DLL) libraries being linked in. This, not surprisingly, is a conflict, and hence causes a runtime crash.
These kinds of errors mean that you are linking together objects that have not all been compiled with the same runtime flag,
/MTd. Sure you could just blindly add
/NODEFAULTLIB:<whatever> to silence the warning, but that doesn’t really solve the issue.
You see, the MSVC compiler embeds library information into every object file it creates. This means that a single file compiled with
/MDd will mess up an entire
/MD build. And this file could be in your code or any dependent static library. What is needed is tool that inspects objects and static libraries. The secret is using the
dumpbin tool, provided with Visual Studio, to parse object files and static libraries. The
/DIRECTIVES option dumps the linker flags embedded inside the object file. You should see
/DEFAULTLIBRARY entries in the output, and this is how the linker decides which libraries to link against.
dumpbin can also be used on static libraries (
.lib files), but you will need the
/ARCHIVEMEMBERS option to see which particular embedded object file the directives are associated with. From here, it’s just a matter of some simple scripting to find out the one object file that was compiled incorrectly.