How to Tell If a Lib Was Compiled with /Mt or /Md

How to tell if a lib was compiled with /mt or /md?

Yes, you could use dumpbin's /DIRECTIVES option to find which runtime libraries the objects in the .lib want to link with:

dumpbin /directives foo.lib

Look for instances of the runtime libraries specified here. For example, you might see:

/DEFAULTLIB:MSVCRTD (module compiled with /MDd)

or

/DEFAULTLIB:MSVCRT (module compiled with /MD)

or

/DEFAULTLIB:LIBCMT (module compiled with /MT)

There will probably be many /DEFAULTLIB directives, so you can search using terms like:

dumpbin /DIRECTIVES foo.lib | find /i "msvcr"

check what run-time static library or dll uses

If it is a .lib file, a static link library, then you don't know anything about the CRT yet. It wasn't linked yet. You can find out about the original programmer's intention, use a hex viewer to look the .lib file, Notepad will do fine as well. You'll see the original command line that was used to compile the .obj files that were embedded in the .lib file. Simply search for "cl.exe", you'll have a good idea what compiler version was used from the path to cl.exe. And you can see the command line options so you'll know if /MD or /MT was in effect. And the /O option, important to have an idea whether you've got a Debug or Release build.

If it is a .dll file then dumpbin.exe /imports is your best choice. The dependency on the msvcrxxx.dll file will be visible, with xxx the version number like "120". If you see it then the name tells you if /MD or /MDd was used, "d" is appended for the Debug version of the CRT If it is missing then you know that /MT or /MTd was used, no hint about the build flavor available.

Following the recommendations from the library owner is always best, you can get into a lot of trouble when the CRT version or build settings of the library doesn't match yours. With non-zero odds that you have to ask him for an update, YMMV.

Conceptual ambiguity between /MD /MT and dll lib

A key aspect of this is differentiating between the build/compile time issues and the runtime issues.

At build time, the compiler and linker need sufficient information on how to compile and construct the code; data definitions, function locations etc. The header files provide most of that detail for the compiler, the linker needs to be able to locate the functions1 to complete the process.

If the dll is provided with a lib as well (as is the case with /MD), this lib contains the minimum required code for the linker to find the functions required and some additional code to load the dll at runtime. A program can be made that does not link with a lib (even though there is a dll), you will then need to load the dll at runtime (via LoadLibrary) and fix up the pointers (via GetProcAddress) to the functions1 you need to call. With a C++ library that is difficult, hence it is generally not attempted, the name mangling make this harder (with a C library it is generally much easier).

If the lib is a static lib with no associated dll (for the runtime this is /MT), then the lib contains all the code needed to run and execute its given functionality. The linker links all the required code up into the target and no additional runtime loading is required.

1 I loosely use the word functions here, but it includes all externals as well.

What difference does /MD, /MT make when compiling object files?

Yes, these options affect the generated code a little bit. Look at this simple code:

#include <errno.h>

int fn() {
return errno;
}

With /MT, this compiles:

call    __errno
mov eax, DWORD PTR [eax]

While with /MD:

call    DWORD PTR __imp___errno
mov eax, DWORD PTR [eax]

So, DLL imported symbols will have a __imp_ prefix, and they are actually a pointer to the real symbol.

What does MT and MD stand for?

DLL and internal may be used as mnemonic to distinguish /MD from /MT.

Should I compile with /MD or /MT?

By dynamically linking with /MD,

  • you are exposed to system updates (for good or ill),
  • your executable can be smaller (since it doesn't have the library embedded in it), and
  • I believe that at very least the code segment of a DLL is shared amongst all processes that are actively using it (reducing the total amount of RAM consumed).

I've also found that in practice, when working with statically-linked 3rd-party binary-only libraries that have been built with different runtime options, /MT in the main application tends to cause conflicts much more often than /MD (because you'll run into trouble if the C runtime is statically-linked multiple times, especially if they are different versions).

mixing code compiled with /MT and /MD

No. /MT and /MD are mutually exclusive.

All modules passed to a given invocation of the linker must have been compiled with the same run-time library compiler option (/MD, /MT, /LD).

Source

Find out whether a lib requires static or dynamic runtimes

dumpbin /directives is your friend:

C:\jm>type 08.cpp
int main() { }

C:\jm>cl /nologo /c /MT 08.cpp
08.cpp

C:\jm>dumpbin /nologo /directives 08.obj

Dump of file 08.obj

File Type: COFF OBJECT

Linker Directives
-----------------
/DEFAULTLIB:LIBCMT
/DEFAULTLIB:OLDNAMES

Summary

60 .debug$S
2F .drectve
7 .text$mn

C:\jm>

Note the /DEFAULTLIB:LIBCMT under "Linker Directives." This linker directive is injected into the object when you compile with /MT (static release CRT). The /MT, /MTd, /MD, and /MDd linker options all cause different runtime libraries to be dragged in. See the documentation for details.

A library is just a collection of objects, so you can use dumpbin /directives on a lib file to get the directives contained in each object in the library. Note that it's possible (though quite uncommon) for different objects in a single static library to be compiled with different runtime library options.



Related Topics



Leave a reply



Submit