What to do when /MT and /MD both required? - c++

This is a sort of follow-up to this question I posted yesterday. My problem regards which runtime C++ libraries to link against. I am using Qt as a framework and QtCreator for my IDE. According to the digia docs here, Qt has been known to have memory problems when built with the /MT flag (which makes your app run against the static runtime libraries). However, I'm also using a 3rd party driver in this app, and the docs on that app specifically say that it won't build unless you link against the static runtime libraries. Sure enough, it compiles fine with the /MT flag, but gives me about 40 linker errors when I remove that setting. (and so far I'm only including one header file from the driver's static library)
So my question is: what's the correct thing to do here? Is there a way to force the driver to expect the dynamic runtime library? Or should I live with Qt's memory management problem? Or is there a way to have Qt link against the dynamic ones and the driver (and the parts of Boost that it requires) link against the static ones? (and keep in mind that I'm doing this in QtCreator, not studio)

Both /MT and /MD are linker options. If you're building multiple modules, you can have multiple options.
In this case, use /MD for Qt and your own code. Wrap the driver in its own DLL, with a non-CRT-dependent API, and link that DLL with /MT. Using COM might be an option. That's certainly not CRT dependent, but it may be overkill.

Related

Why do i need to specify runtime library type for static lib building?

Does it link against the runtime library when i build my static lib? Does it "put" the code from runtime lib into my lib?
Or is it just information for linker, so that when it links final exe(dll) it knows what version of runtime library to use for this particular static library?
Do i need to use the same version of runtime library in all my static libs and dlls?
Do i need to use the same type (/MT /MTd /MDd ...) in all my static libs and dlls?
And one more short question, is it usual that static windows libraries are twice the size of linux static libraries?
Or is it just information for linker, so that when it links final
exe(dll) it knows what version of runtime library to use for this
particular static library?
Yes.
Do i need to use the same version of runtime library in all my static
libs and dlls?
I strongly strongly advise it. You will get a mess of linker errors if you don't.
Do i need to use the same type (/MT /MTd /MDd ...) in all my static
libs and dlls?
Yes.
If you are releasing a DLL to be consumed by a 3rd-party, you may want to provide them with YourLibraryD.dll which uses the /MTd flag, and a YourLibrary.dll which uses /MT. Have different solution configurations for each. Nobody uses the single-threaded versions any longer, because the performance penalty is mostly irrelevant now and not worth the risk.
EDIT: Even if you aren't releasing to a 3rd party, you still want to make sure you link to the right DLL when in debug -vs- release mode. This is because when you build YourApp.exe in Debug, which uses /MTd, you will want it to link to YourLibraryD.dll. When you build YourApp.exe in Release, which uses /MT, you will want it to link to YourLibrary.dll in release mode. You could keep the DLL name the same and use the directory to disambiguate: so then you link to bin\debug\YourLibrary.dll in debug mode, and bin\release\YourLibrary.dll in release mode. Sorry if this is beyond your question, it is just good to know when you first switch build configurations and suddenly you start getting linker errors.

Shouldn't Boost::Thread libraries be deployed with my project generated with /MD?

I am developing an application in VS2005 which uses Boost 1.54. After messing up with compilations, I decided to download the "alredy baked" VS8.0 Win32 binaries, and there they go.
Now the thing is, the application is being generated with the /MD option, which means, correct me if wrong, that it is being dynamically linked (external dependencies shall be provided in means of DLL files).
I have used Boost::Thread in my application, and it runs fine in my computer. As it is generated with /MD, it is supposed to require DLLs in other computers, isn't it?
However, when asking a peer (who does not work with Boost) to run my app, it simply runs fine. Wasn't it supposed to shout with a DLL missing error?
Thanks.
/MD is a flag dedicated to the C run time, it is not related to Boost.
By default, i think Visual Studio links statically Boost. If you want to link dynamically, you need to add a flag BOOST_ALL_DYN_LINK
Also, i would recommend the excellent Walker Dependency whenever you want to check dynamic dependencies

How to build and link LuaJIT statically (VS 2013)

Premise : I'd like my C++ application not to depend on whatever Microsoft Visual C++ redistributable, so I can ship my executable file that will work out of the box.
What I've done first : switching the runtime library to Multithread (/MT) from DLL Multithread (/MD) in order to avoid the need for msvcr110.dll (and shouldn't VS 2013 require the 120 version, as it's the compiler version ?). To do that I also had to recompile another library I'm using with the same runtime library, and that worked. I had my .exe which could be ran anywhere without problems (or I wasn't aware of, haha).
Then I added some functionalities that make use of LuaJIT. I've built LuaJIT by the msvcbuild.bat provided with the package and it worked like a charm, but now my executable requires the msvcr110.dll to run. I guess that's because LuaJIT was compiled with the /MD flag, but I'd like to know if there is a proper way to do what I want.
You should run msvcbuild.bat with static command line parameter.
I didn't test this, but you most likely need to use the /MT flag on each piece of the compilation you do. In this case, both your main program, and LuaJIT. In that msvcbuild.bat file (https://github.com/luvit/luajit-2.0/blob/master/src/msvcbuild.bat) you can see that they are explicitly specifying /MD (line 17). Methinks that is your problem. Change it to /MT and see.

MT or MD for static release?

In the static release of my application, I do not want the user to need the msvcrt runtime. My application depends on another library that I compile myself. Should this library use multithreaded or multithreaded DLL when compiling it? The library is static compiled.
Thanks
VC++'s license agreement prohibits the distribution of debug builds on any computer that doesn't already have VC++ installed, so your only option is to use /MTd or /MDd for debug builds while developing the application and /MT for the release build meant for distribution.
You should use DLL CRTs wherever possible, you can end up with trouble if you start linking multiple copies statically. If you know for a fact that you're compiling the final product, then you could link statically.

Should I compile with /MD or /MT?

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.