The C++ (and C, though it matters less there) standard states that all translation units in a program need to have the same definition; and that includes things like compiler switches. For instance, on MSVC++, one must link to the right version of the C runtime library (/MT
versus /MD
versus /MTd
versus /MDd
) in all translation units.
However, there are a couple of third party dependencies we'd like to use, and there are a couple of things:
/MD
and /MDd
, while another forces /MT
and /MTd
)We aren't sure what the best way to handle these kinds of things are. We have discussed the following options:
We don't know what to do though; and we can't believe that we are alone in having these kinds of issues. Should we do one of those options above, or some third alternative that I've not thought of?
You don't strictly speaking need all your libraries to link to the same runtime. Assuming they're DLL's, it is only a problem if they pass CRT data structures through the DLL boundary. Creating a FILE*
in a DLL using one runtime, and using it from a DLL which is linked against another runtime is a recipe for disaster. Calling malloc
or new
from a DLL using one runtime, and free
/delete
from another will cause lots of fun problems.
But as long as all the CRT-related stuff is kept internal in the DLL, you can safely link to a DLL which uses another CRT. That also means that your debug build can use a library linked against the release CRT. Again, as long as you don't try to mix CRT data structures across libraries.
Note also that most compiler flags do not affect the ABI, and so they can safely be different between libraries (or files). The ones that do change the ABI are generally obvious, like if you force packing or stack alignment.
So what we do is basically this:
We currently depend on three different VS runtimes (2005, 2008 and 2010), which is a pain to deal with, but it works. And for one or two of them, we always use the release version, even in debug builds of our own code.
It's a bit messy to maintain, but it works. And I can't really see a better way to do it.
Of course, you should minimize how many third-party dependencies you have, and when you choose a third-party library, its build system should definitely be a factor to consider. Some are a lot more painful to work with than others.
But in the end, you'll probably end up having to use a few libraries that just don't have well-behaved build systems, or which would be so painful to build that it's just not worth the effort, or where you can't create a debug version of the library. And then just take what you can get. Let it use whatever runtime it likes to use.
I assume that you are intentionally not mentioning any specific libs?
Anyway, you should ask yourself whether you really need this 3rd party code in your build system.
The 3rd party libs we use are compiled once (with their respective build scripts) and checked for the right VC switches, and then the DLL or LIB file is checked into source control of the app that uses the lib.
So the compilation of a 3rd party lib is something we only do once per 3rd party release and we don't burden our build system with the intricacies of building the 3rd party libs.
I guess there are valid arguments for either approach, and maybe you can provide some details in the question why you need/want to have the 3rd party libs inside your build system.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With