Why is runtime library a compiler option rather than a linker option? - c++

I'm trying to build a C/C++ static library using visual studio 2005. Since the selection of the runtime library is a compile option, I am forced to build four variations of my library, one for each variation of the runtime library:
/MT - static runtime library
/MD - DLL runtime library
/MTd - debug static runtime library
/MDd - debug DLL runtime library
These are compiler options, not linker options. Coming from a Linux background, this seems strange. Do the different runtime libraries have different calling conventions or something? Why can't the different runtime libraries be resolved at link time, i.e. when I link the application which uses my static library?

These options may add defines (__DLL and __DEBUG for example) that are used in the runtime library header files. One common thing to do is to add __declspec(dllimport) to function declarations when linked dynamically.
The compiler also seems to use these to assist the linker in linking to the correct libraries. This is explained in the MSDN.

One side effect of the C preprocessor definitions like _DLL and _DEBUG that zdan mentioned:
Some data structures (such as STL containers and iterators) may be sized differently in the debug runtime, possibly due to features such as _HAS_ITERATOR_DEBUGGING and _SECURE_SCL. You must compile your code with structure definitions that are binary-compatible with the library you're linking to.
If you mix and match object files that were compiled against different runtime libraries, you will get linker warnings such as the following:
warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs

The compiler needs to know if you are generating single threaded or multi-threaded code. By default the compiler generates thread safe code (multi-threaded). You have to tell it if you want single thread code.If you change the default the compiler changes the default run-time library (you can always override this in the linker command options, just be sure that the library you pick has the same code structure as your object files: single-threaded static, multi-threaded static or multi-threaded DLL). Note that there is no single-threaded DLL option (by definition the run-time library DLL will have been built as thread safe as it is shared by multiple apps).

If you ignore the static runtime then you get the same options as Linux.
I know static runtime can be usful but I have never actually needed it. Also it leads to potential problems dealing with allocation/deallocation of memory and as a result I find it easier to just to use the DLL runtime.
Having Release/Debug version is the same as Linux/Unix though.
Though for effeciency I reasons I alos build a single thread and multi thread versions of libraries.

I believe the reason behind this is that SEH (structured exception handler) code will be generated differently depending on which runtime library you link against.

There is different machine code generated for DLL's and static libraries.
And on Linux you have to do the same, the compiler flag is called -fPIC if you want to build a shared library. Otherwise on AMD64 and SPARC (and maybe others) it will crash. On i386 architecture the linker is clever enough and does not share the library in memory so it won't crash.

Related

"Mixing a dll boost library with a static runtime is a really bad idea..."

I have two projects in a Visual Studio solution. One builds a static LIB, the other builds a dynamic DLL. Both use static runtime linking (/MT and /MTd), and both use Boost. Boost was not my decision - I wanted to chuck it but I was overruled by committee.
The LIB builds fine, but the DLL coughs up an error from auto_link.hpp (line 354): "Mixing a dll boost library with a static runtime is a really bad idea...".
#if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK)
# define BOOST_LIB_PREFIX
#elif defined(BOOST_DYN_LINK)
# error "Mixing a dll boost library with a static runtime is a really bad idea..."
#else
# define BOOST_LIB_PREFIX "lib"
#endif
I did not define BOOST_DYN_LINK. It seems Boost is making a leap that since I am building a DLL (_USRDLL and _WINDLL are defined), I must want dynamic runtime linking (/MD or /MDd, which defines _DLL) or DLL linking against Boost. This is incorrect as I specifically asked for static linking (/MT or /MTd).
I filed a bug report against Boost for its incorrect assumptions, but that does not help me with using the library. In the report, the Boost maintainers insist that I am setting it (despite the fact that an audit showed I am not; and Boost manipulates it in at least 30 files). I found one answer on the Boost mailing list, which essentially states to change my project settings to accomodate Boost.
Changing to Dynamic Runtime Linking (/MD and /MDd) is not feasible since static linking was chosen (1) due to security considerations, and (2) another library uses static linking. This is non-negotiable - we have no choice.
To summarize for clarity (TLDR): I want to use static linking for everything, while my output program is a DLL (not a static LIB, not an EXE). Everything is linked statically within the DLL.
Does anyone know how to use this library on Windows to build a DLL with static linking?
Short version: listen to the guys on the Boost ML. Boost doesn't support what you're trying to do, and it's a bad idea anyway. Best to accept that and make the other library use the dynamic runtime.
Longer version:
You seem to be misunderstanding what Boost is telling you. You're trying to parse through the Boost source code instead of just reading what it's saying:
auto_link.hpp (line 354): "Mixing a dll boost library with a static runtime is a really bad idea...".
Boost thinks that you are building a DLL, while simultaneously linking statically to the runtime libraries. Which is exactly what you're doing; Boost has accurately detected what you are trying to do.
Your problem is that the Boost library does not support being built into a DLL that is not dynamically linking to the runtime libraries. The reason for that is that it is "a really bad idea." So they check to see if you're trying to do that and stop your build with an error message reminding you of this fact.
The "freetards" at Boost who don't know how to make something work "out of the box" prevent this because statically linking to the runtime in a DLL is usually a mistake by the user. It's either made accidentally or through ignorance of the major problems this can create.
If you statically link to the runtimes, each DLL/exe will have its own copy of the runtimes, with their own global variables. And since the heap is managed via globals, this means that each DLL/exe will have its own heap. So if you try to free memory allocated in another address space... boom. And this is a lot easier than you think if you're not careful.
This can cause other problems as well. The "freetards" are trying to stop you from shooting yourself in the foot. But obviously you know better than to "force their crap on honest and unsuspecting users" who might want to be advised when they're about to drive over a cliff.
Now, you could simply remove the error message. Most of Boost is headers, so as long as you're not actually linking to any of its .libs, you should be fine. However, I'd guess that "auto_link.hpp" is only used by the parts of Boost that are .libs, odds are good that the fact you encountered it to begin with means you're trying to link to a Boost .lib.
Changing to Dynamic Runtime Linking (/MD and /MDd) is not feasible since static linking was chosen (1) due to security considerations, and (2) another library uses static linking.
If security is a consideration, you should be aware of this: the very fact that you're building a DLL means that your application is potentially open to DLL injections, regardless of how you link to the runtimes. So I don't see how dynamic linking is any less secure than static.
This issue is indeed a fault with boosts settings.
For some unknown reason (that I cannot determine to be logical - as it has not effect). Boost Python will force dynamic linking of boost, regardless of user options
In short, if you have boost-python in your project, boost incorrectly prevents static-linking of boost with the /MT switch.
This problem is resolved easily by defining BOOST_PYTHON_STATIC_LIB before including the boost headers.
I don't know how it affected build exactly, but running cmake with -DCMAKE_BUILD_TYPE=Relase helped. Probably one of the mentioned here flags is a default for Release.

Why does intel compiler produce output that requires libiomp5mt.dll, even though I ask for static linking?

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.

C++ visual studio libraries

Is there any way to make static libraries built in Microsoft Visual Studio independent from used CRT (with debug support / without it)?
I mean like, for simple C library it is possible to generate code using gcc and then use the same static library in visual studio. The resulting library.a file is completely independent from /MT or /MDd switches and does not result in warning / linking errors.
Comparing to Visual Studio default behaviour, you would have to build two versions of the same library - for Debug / Release modes independently. If you try to use the Release version in Debug configuration or vice-versa, this results in ugly warnings (warning LNK4098: defaultlib "LIBCMT" ...), but sometimes does not compile due to different runtimes?
Is there any way to avoid this? Or probably I'm doing something wrong?
To make a lib that will link in regardless of runtime selection it is necessary to use two switches:
/MT to build against the basic release runtime, /Zl to omit the default library names.
Building against the dll runtimes will cause the compiler to decorate all the runtime symbols with __imp_ (so, for example, it will try and link against __imp__fread rather than _fread). So you have to choose one of the static runtimes.
The compiler does an implicit default library pragma, depending on the lib selected:
#pragma comment(lib,"libcmtd.lib")
is how it looks in code. The /Zl causes the compiler to omit all these directives - (implicit and explicit) from the resulting .obj (and hence .lib) file. So the result will should link cleanly without causing default library conflicts.
No. The object files for the default release and debug configurations are completely different -- debug object binaries are relocatable machine executable object code, release object binaries are simply an intermediate representation of the original code. That is, the backend is in the linker for release builds, but is in the compiler for debug builds. Putting the backend is in the Linker allows the compiler back end to make more intelligent decisions with respect to optimization of your program, at the expense of longer compilation times.
Is there a problem with distributing 2 versions of the library? I don't claim to speak for everybody, but I always like to have a debug version, compiled against the static debug libs, with asserts and extra checking compiled in. (Symbols are good, too, of course!) The asserts and checks are helpful, the stack traces are usually better when the thing crashes in the library code, and it's often easier to read the disassembly.

How do I create a Win32 DLL without a dependency on the C runtime

Using Visual Studio 2008 and its C/C++ compiler, how do I create a Win32 DLL that is dependent only on other Windows DLLs, and has no dependency on the Microsoft C runtime?
I have some C code I want to place in a DLL that is entirely computation, and makes almost no use of C library functions.
For those it does use (eg memcpy), I'm happy to rework the code to use the Win32 API equivalents (eg CopyMemory).
Use the /NODEFAULTLIB linker option and (of course) make sure you have no actual dependencies on the runtime. You'll also have to specify & define your own entry point for the DLL using the /ENTRY linker option or alternatively have your own entry point function that matches the name expected by the compiler/linker (for a dll, that's _DllMainCRTStartup).
Matt Pietrek's article from way back when on LIBCTINY will probably have all the information you need:
http://msdn.microsoft.com/en-us/library/bb985746.aspx
for "Debug" mode try this:
Go to Project\[Projectname] Properties...
Open Configuration Properties
Open C/C++
Open Code Generation
For Runtime Library Select Multi-threaded Debug (/MTd) instead of Multi-threaded Debug DLL (/MDd)
for "Release" mode, do same steps except that selecting Multi-threaded (/MT) in the last step.
This causes any C Runtime function that used in your program to be statically-linked to your binary file.
You may have more dependencies on the CRT than you think. It tears down resources like thread local storage, and global class initializers are run by the CRT before main().
Consider linking with a static CRT, as someone said, and if you really really don't want to, use /NODEFAULTLIB and /ENTRY as someone else said.
Oh, and instead of reworking memcpy, consider using the super-fast compiler intrinsic for it. You can turn on intrinsics with /Oi.
The /NODEFAULTLIB linker flag is not actually the proper flag. It will ignore all default libs, including others like uuid.lib.
What you want is the /Zl compiler option, "omit default library name in .OBJ".
You'd have to make sure none of the Win32 DLLs you use need the C runtime as well or else you back at square one. Compiling your DLL statically won't matter if one of the Win32 DLLs depends on the C runtime.
The only way I can see this working is to statically link ALL your dependent DLLs (if that is even feasible) into your DLL. This of course means you would have to recompile to take advantage of any DLL updates.
Some Windows libraries depend on the C runtime (ODBC32.DLL, for example)
so I think you are on a hiding to nothing here. Why would you want to do this, anyway?
Compile it with static microsoft lib.

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.