In Visual Studio, there's the compile flags /MD and /MT which let you choose which kind of C runtime library you want.
I understand the difference in implementation, but I'm still not sure which one to use. What are the pros/cons?
One advantage to /MD that I've heard, is that this allows someone to update the runtime, (like maybe patch a security problem) and my app will benefit from this update. Although to me, this almost seems like a non-feature: I don't want people changing my runtime without allowing me to test against the new version!
Some things I am curious about:
How would this affect build times? (presumably /MT is a little slower?)
What are the other implications?
Which one do most people use?
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).
If you are using DLLs then you should go for the dynamically linked CRT (/MD).
If you use the dynamic CRT for your .exe and all .dlls then they will all share a single implementation of the CRT - which means they will all share a single CRT heap and memory allocated in one .exe/.dll can be freed in another.
If you use the static CRT for your .exe and all .dlls then they'll all get a seperate copy of the CRT - which means they'll all use their own CRT heap so memory must be freed in the same module in which it was allocated. You'll also suffer from code bloat (multiple copies of the CRT) and excess runtime overhead (each heap allocates memory from the OS to keep track of its state, and the overhead can be noticeable).
I believe the default for projects built through Visual Studio is /MD.
If you use /MT, your executable won't depend on a DLL being present on the target system. If you're wrapping this in an installer, it probably won't be an issue and you can go either way.
I use /MT myself, so that I can ignore the whole DLL mess.
P.S. As Mr. Fooz points out, it's vital to be consistent. If you're linking with other libraries, you need to use the same option they do. If you're using a third party DLL, it's almost certain that you'll need to use the DLL version of the runtime library.
I prefer to link statically with /MT.
Even though you do get a smaller executable with /MD, you still have to ship a bunch of DLLs to make sure the user gets the right version for running your program. And in the end your installer is going to be BIGGER than when linking with /MT.
What's even worse, if you choose to put your runtime libraries in the windows directory, sooner or later the user is going to install a new application with different libraries and, with any bad luck, break your application.
The problem you will run into with /MD is that the target version of the CRT may not be on your users machine (especially if you're using the latest version of Visual Studio and the user has an older operating system).
In that case you have to figure out how to get the right version onto their machine.
from http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx:
/MT Defines _MT so that multithread-specific versions of the run-time routines are selected from the standard header (.h) files. This option also causes the compiler to place the library name LIBCMT.lib into the .obj file so that the linker will use LIBCMT.lib to resolve external symbols. Either /MT or /MD (or their debug equivalents /MTd or /MDd) is required to create multithreaded programs.
/MD Defines _MT and _DLL so that both multithread- and DLL-specific versions of the run-time routines are selected from the standard .h files. This option also causes the compiler to place the library name MSVCRT.lib into the .obj file.
Applications compiled with this option are statically linked to MSVCRT.lib. This library provides a layer of code that allows the linker to resolve external references. The actual working code is contained in MSVCR71.DLL, which must be available at run time to applications linked with MSVCRT.lib.
When /MD is used with _STATIC_CPPLIB defined (/D_STATIC_CPPLIB) it will cause the application to link with the static multithread Standard C++ Library (libcpmt.lib) instead of the dynamic version (msvcprt.lib) while still dynamically linking to the main CRT via msvcrt.lib.
So if I am interpreting it correctly then /MT links statically and /MD links dynamically.
If you are building executable that uses other dlls or libs than /MD option is preferred because that way all the components will be sharing same library. Of course this option should match for all the modules involved i.e dll/lib/exe.
If your executable doesn't uses any lib or dll than its anyone's call. The difference is not too much now because the sharing aspect is not into play.
So maybe you can start the application with /MT since there is no compelling reason otherwise but when its time to add a lib or dll, you can change it to /MD with that of the lib/dll which is easy.
Related
I'm reading about /MT and /MD, but I'm a little confused about it
HEAR is something I don't completely understand :
/MT Causes your application to use the multithread, static version of the run-time library. Defines _MT and causes the compiler to place the library name LIBCMT.lib into the .obj file so that the linker will use LIBCMT.lib to resolve external symbols.
what does it mean?
If you link with /MD or /MDd your program is going to need the CRT dlls in order to run. typically they are called something like msvcp100.dll for the C++ runtime and msvcr100.dll for the C runtime. If you are deploying your application using an installer, you can add a package with these to your installer so the dlls are going to be there when someone runs the application. If on the other hand you are going to deploy your application just as a single stand alone exe, your users are going to need a copy of these dlls. The latest versions of these dlls usually come with windows itself (not the debug ones) but if your user is running an older version of windows it may not have the needed dlls.
Linking your application to the static version of the CRT saves this whole headache for the price that the exe is slightly bigger (since it contains the CRT in it)
If you do use /MT (Static CRT) you have to make sure that everything else that you statically link with uses /MT as well. otherwise you'll end up with an executable where part of the code uses the static CRT and part is still depends on the CRT DLL. Other than defeating the basic purpose not needing the CRT DLL, this can also cause other problems.
To make sure what DLLs your exe depends on you can use the dependency walker.
I have a DLL and 3 Applications which uses this DLL. (These application do not run simultaneously)
Out of 3 Applications, 2 work perfectly but 1 application doesn't get response from one DLL function after some time (at 7th function call, to be specific).
Also, The code works properly if I use debug version of Application OR my DLL. It stops in Release version only.
After spending 2 sleepless nights, I figured out that If I change project property of DLL from /MD to to /MT, this application works properly.
I have no clue why this thing is happening. Can anyone please explain this for the sake of a sleep deprived programmer!
Update:
I would be releasing this DLL in market and I can not say whether user application will be built is /MT or /MTD or whatever... Is there any way to make sure that it will work with any application.
In Windows speak, the EXE and DLL files are modules.
Each modules compiled dynamically (/MD) share one heap.
So in the dynamic modules, if one module calls malloc (or new)
and another module does the free (or delete) on the object all is good.
Each module compiled to link in the C runtime statically gets its own heap.
If one static module allocates an object and a different static or dynamic
module tries to free the object, the program will crash because the allocate
and free are against different heaps.
Allocating and freeing memory across module boundaries
/MD links the runtime as dynamic, if the computer you have a runtime properly installed, then compiling as /MT would work, since the runtime will be included in the binary.
That may also explain while it works when you compile it as Debug mode, in debug mode, a debug version of the runtime is statically linked into the binary.
Look here for some discussion about the topic.
UPDATE
Another problem may be that the modules that the dll were compiled with different options, as stated in this msdn article:
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).
I'm compiling an openmp project with the /MT switch (or equivalently in visual studio settings, "C++: Code Generation: Runtime Library: Multi Threaded".
Visual Studio still, however, reports that my output requires libiomp5mt.dll (multi threading dll) when I thought the above setting was asking for static linking.
Is there another option somewhere I missed?
Alternatively, if the dll is a requirement, I presume I'm allowed to redistribute Intel's dll alongside my own application?
The Intel website says:
You are strongly encouraged to dynamically link in the compatibility OpenMP* run-time library libiomp (i.e libiomp5md.lib and libiomp5md.dll , located in the [Compiler Dir]\lib directory), even if other libraries are linked statically. Linking to static OpenMP* run-time library (i.e libiomp5mt.lib) is not recommended. Because multiple OpenMP libraries in one appliation causes performance problems (too many threads) and may cause correctness problems if more than one copy is initialized.
So although you can configure OpenMP to link statically, and this configuration is independent of the C runtime, you are recommended not to.
Intel's OpenMP licence allows for royalty free redistribution as far as I can tell. You should check the licence that came with your OpenMP just to be on the safe side.
The above switch is for C++ runtime only, OpenMP is an external library which is not a part of the C++ runtime. Hence the switch doesn't have any effect on it.
As per the redistribution of the DLL, look at the license of the product the DLL was shipped with. You're probably allowed to redistribute it.
There are two ways of creating code libraries. As static Libs and as Dlls (Extentsions: *.lib and * dll).
If there is only a Dll available, you can only link to it dynamically, not statically. What may be confusing you is that a Dll usually has a lib file you link to which has all the entry points into the Dll.
I have a dll that I distribute that will not run on some windows OS. Using dependancy walker I discover msvcp90d.dll missing on these systems. I DO NOT want any run time dependancies that require the C++ redistributable, and since the application that calls the DLL is not written in C++, it does not have any dependancy on the C++ redistributable.
I am guessing the I left the DEBUG option in the linker preferences on when I compiled the dll which is why it needs msvcp90d.dll?
ADDED:
Appologies, I pasted the wrong dll name in my original question.... too many hours in front of the monitor...
THe dll is a third party dll that I did not write compiled by me in VS2008.
MSVCP90 is nothing to do with debug (that'd be msvcp90d). You can remove your dependency by switching the compiler to /MT (instead of /MD). You also need to ensure that every static library you link to was also compiled /MT.
I recommend against building apps /MT because it has a significant negative effect on system performance and makes servicing take longer in the event of a security issue with the CRT.
Finally, note that /MT means that your CRT is private. So you must ensure that CRT/STL types don't pass across your DLL boundary.
Martyn
Your options as I see them:
Compile the DLL with the /MT option to use static linking to the C runtime.
Continue with dynamic linking to the runtime, but distribute the C runtime with your app.
It needs MSVCP90.dll because the dll was compiled with Visual Studio 2008 most likely. That is the release runtime. The short answer is if you don't want C++ runtime dependencies don't use C++ libraries or applications.
However you can do any of the following to solve your problem:
Install the redistributable to the target system to satisfy the dependency
Remove the dependency on that dll from your application
Recompile the dll against the version of VC you prefer that is already present on the target system
After going through a lengthy process to rename a project, my DLL project will not build in Debug mode (Release builds work):
MSVCRTD.lib(msvcr90d.dll) : error LNK2005: _CrtDbgReportW already defined in LIBCMTD.lib(dbgrpt.obj)
This project, and the five static libraries it depends on, are set to use "Multi-threaded Debug (/MTd)" (under C/C++|Code Generation|Runtime Library). I believe LIBCMTD.lib is the one for multi-threaded debug, but what is MSVCRTD.lib, and what could be causing this error?
If it makes a difference, this DLL is for Windows CE.
LIBCMT is what you need for /MT, MSVCRT is what you need for /MD. You are linking .obj and .lib files that were mixed, some compiled with /MT some with /MD. That's not good.
Usually it is the .lib files that cause the problem. Review their build settings and make sure their /M option is the same as your DLL project.
Also, beware of the trouble you can get into if the DLL was compiled with /MT. You'll have major problems when the DLL returns pointers to objects that the client needs to release. It can't, it doesn't use the same memory allocator.
The MSDN article on LNK4098 has a very useful table: it tells you which libraries to manually add to the "Ignore specific library" list, depending on which CRT you're using. In your case, you should ignore all of these:
libc.lib, libcmt.lib, msvcrt.lib, libcd.lib, libcmtd.lib
Observe that the reported library is in this list too. The problem is described in more detail in KB154753 ... libraries that a program will link with when built by using Visual C++
My interpretation of this is that in certain situations the algorithm that automatically picks which CRT libraries to link your code with will pick several conflicting libraries.
What is release set too? Setting a DLL to multithreaded debug can cause problems if you allocate memory that something accesing the DLL tries to free (they will be allocated in different heaps, for example). Try setting multi-threaded debug DLL.
Your link problem probably arises because a library you are linking to is expecting multithreaded debug DLL so the linker tries to link both and your link fails ...
The problem is the msvcr90d.dll is not in the windows ce image. It must be deployed with the application. The msvcr90d.dll is located in $(VCInstallDir)/ce/bin/$(ARCHFAM).
http://stackoverflow.com/questions/15959877/windows-ce-6-0-and-runtime-link-to-debug-dll-mdd