“Mixing a dll boost library with a static runtime

2020-02-26 00:37发布

问题:

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?

回答1:

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.



回答2:

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.