Opened 11 years ago

Last modified 7 years ago

#6644 new Bugs

Windows: auto_link.hpp incorrectly errors with "Mixing a dll boost library with a static runtime is a really bad idea..."

Reported by: noloader@… Owned by: Ralf W. Grosse-Kunstleve
Milestone: To Be Determined Component: python USE GITHUB
Version: Boost 1.48.0 Severity: Problem
Keywords: Windows auto_link /MT /MD DLL Cc: owasp-esapi-c++@…

Description

I'm building a DLL which uses *static* runtime linking. Static runtime linking uses the /MT (and /MTd) switch. When Boost is compiled with under the DLL, the following error is reported:

C:\Users\Public\boost-trunk\boost/config/auto_link.hpp(354) : fatal error C1189: #error : "Mixing a dll boost library with a static runtime is a really bad idea..."

According to "/MD, /MT, /LD (Use Run-Time Library)", http://msdn.microsoft.com/en-US/library/2kzt1wy3(v=vs.90).aspx:

/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.

For completeness, here is the switch for dynamic runtime linking:

/MD - Causes your application to use the multithread- and DLL-specific version of the run-time library. Defines _MT and _DLL and 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 MSVCR90.DLL, which must be available at run time to applications linked with MSVCRT.lib...

To summarize, "_MT" is defined for both static and dynamic linking. "_DLL" is defined for just dynamic linking. And because I am building a DLL, "_WINDLL" is also defined.

Perhaps the following would be better logic for auto_link.hpp (my apologies for not trying to figure out all the Boost defines):

#if defined(BOOST_OS_WINDOWS) && defined(_MT) && !defined(_DLL) # define BOOST_OS_WINDOWS_STATIC 1 #elif defined(BOOST_OS_WINDOWS) && defined(_MT) && defined(_DLL) # define BOOST_OS_WINDOWS_DYNAMIC 1 #elif defined(BOOST_OS_WINDOWS) # pragma warning("Neither static nor dynamic runtime linking has been picked up") #endif

Attachments (2)

static-dynamic.txt (794 bytes ) - added by noloader@… 11 years ago.
Various settings for EXE, DLL, staic and dynamic runtime linking
BOOST_DYN_LINK.png (52.7 KB ) - added by noloader@… 11 years ago.
Boost is defining BOOST_DYN_LINK somewhere

Download all attachments as: .zip

Change History (15)

by noloader@…, 11 years ago

Attachment: static-dynamic.txt added

Various settings for EXE, DLL, staic and dynamic runtime linking

comment:1 by noloader@…, 11 years ago

Second try with sample defines.

#if defined(BOOST_OS_WINDOWS) && defined(_MT) && !defined(_DLL)
# define BOOST_OS_WINDOWS_STATIC 1
#elif defined(BOOST_OS_WINDOWS) && defined(_MT) && defined(_DLL)
# define BOOST_OS_WINDOWS_DYNAMIC 1
#elif defined(BOOST_OS_WINDOWS)
# pragma warning("Neither static nor dynamic runtime linking has been picked up")
#endif

comment:2 by anonymous, 11 years ago

Forgot to add....

When I build a static LIB (not DLL) using static runtime linking, Boost compiles correctly. So I'm not sure where the leap is made that "I'm building a DLL (with static linking), so I must want to use Boost as a DLL"

comment:3 by noloader@…, 11 years ago

Undefining BOOST_DYN_LINK in my project - no joy.

comment:4 by noloader@…, 11 years ago

//
// auto_link.hpp
// select linkage opt:
//
#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

The above appears broken. I just verified _DLL is *not* defined. Additionally, I did *not* define BOOST_DYN_LINK. I don't know about _RTLDLL, but I did not define it either.

Finally, there does not appear to be a BOOST_STATIC_LINK that I can define.

comment:5 by John Maddock, 11 years ago

Resolution: worksforme
Status: newclosed

I suspect you have BOOST_DYN_LINK defined somewhere in your project settings (or those inherited by your project which can be hard to track down). Take a look at the command line tab in the IDE to see what's set.

For me I have:

/I"M:\data\boost\trunk" /ZI /nologo /W3 /WX- /Od /Oy- /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /Gm /EHsc /RTC1 /MTd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Yu"StdAfx.h" /Fp"Debug\dll_test.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /analyze- /errorReport:queue 

And building the following as a DLL:

#include "stdafx.h"

#define BOOST_LIB_DIAGNOSTIC
#include <boost/regex.hpp>


void f()
{
   boost::regex e("abc");
}

Builds just fine and links to: libboost_regex-vc100-mt-sgd-1_49.lib.

If you have a self contained test case (including the IDE project files) that reproduces please reopen, but please check the actual command line passed to the compiler first.... Oh and double check that boost/config/user.hpp hasn't been modified.

in reply to:  5 comment:6 by anonymous, 11 years ago

Replying to johnmaddock:

I suspect you have BOOST_DYN_LINK defined somewhere in your project settings (or those inherited by your project which can be hard to track down). Take a look at the command line tab in the IDE to see what's set.

Actually, its not defined by me. Below is a search of the term. It only shows up in Boost gear.

Find all "BOOST_DYN_LINK", Subfolders, Find Results 1, "Entire Solution"

C:\Documents and Settings\All Users\boost-trunk\boost\config\auto_link.hpp(23):BOOST_DYN_LINK: Optional: when set link to dll rather than static library.

C:\Documents and Settings\All Users\boost-trunk\boost\config\auto_link.hpp(346):#if (defined(_DLL)
defined(_RTLDLL)) && defined(BOOST_DYN_LINK)

C:\Documents and Settings\All Users\boost-trunk\boost\config\auto_link.hpp(348):#elif defined(BOOST_DYN_LINK) C:\Documents and Settings\All Users\boost-trunk\boost\config\auto_link.hpp(414):#if defined(BOOST_DYN_LINK) C:\Documents and Settings\All Users\boost-trunk\boost\config\auto_link.hpp(415):# undef BOOST_DYN_LINK Matching lines: 5 Matching files: 1 Total files searched: 233

by noloader@…, 11 years ago

Attachment: BOOST_DYN_LINK.png added

Boost is defining BOOST_DYN_LINK somewhere

in reply to:  5 comment:7 by anonymous, 11 years ago

Replying to johnmaddock:

I suspect you have BOOST_DYN_LINK defined somewhere in your project settings

See attached. Boost is manipulating (or doing something with) BOOST_DYN_LINK in at least 30 files.

Take a look at the command line tab in the IDE to see what's set.

As requested (I removed the list of file names):

cl /Od /I "../esapi" /I "../errors" /I "../reference" /I "../deps" /I "C:\Documents and Settings\All Users" /I "C:\Documents and Settings\All Users\boost-trunk" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "_STATIC_CPPLIB" /D "ESAPI_MS_DLL_EXPORTS" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MTd /Fo"C:\Documents and Settings\Jeffrey Walton\Desktop\owasp-esapi-c++\VS2008
Esapi-Windows\Temp\Debug\x86\esapi-dll
" /Fd"C:\Documents and Settings\Jeffrey Walton\Desktop\owasp-esapi-c++\VS2008
Esapi-Windows\Temp\Debug\x86\esapi-dll\vc90.pdb"

This appears to be a Boost configuration problem.

comment:8 by Steven Watanabe, 11 years ago

BOOST_DYN_LINK is an internal macro used by the auto link machinery. The user level macros are BOOST_ALL_DYN_LINK and BOOST_<library name>_DYN_LINK.

comment:9 by anonymous, 11 years ago

Using your command line and the test program I posted above the output message I see is:

Linking to lib file: libboost_regex-vc100-mt-sgd-1_49.lib

which is the static regex lib as expected/required.

As Steven has correctly pointed out (my bad) BOOST_DYN_LINK is an internal macro set just before including the auto-link machinery. For regex it is only set if BOOST_REGEX_DYN_LINK or BOOST_ALL_DYN_LINK are defined: these are user settable macros, we don't set them.

Try adding:

#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_REGEX_DYN_LINK)
#error "Oops"
#endif

Right before you include boost.regex in your code, my guess is the error will be triggered, and then you just have to figure out where those defines are coming from.

HTH, John.

comment:10 by george@…, 10 years ago

#define BOOST_PYTHON_STATIC_LIB before including <boost/python.hpp> in your project. Default for Python lib is dynamic linking. I'm using Boost 1.52.

comment:11 by darthpjb@…, 7 years ago

I can both confirm that this issue is still present - and also that it is still caused by boost-python. If BOOST_PYTHON_STATIC_LIB is not defined, python defines BOOST_DYN_LINK - and prevents static linking of all boost libraries.

in reply to:  11 comment:12 by darthpjb@…, 7 years ago

Resolution: worksforme
Status: closedreopened

Apologies for the double-post, but this issue-tracker seems to be having a few problems at the moment.

Replying to darthpjb@…:

I can both confirm that this issue is still present - and also that it is still caused by boost-python. If BOOST_PYTHON_STATIC_LIB is not defined, python defines BOOST_DYN_LINK - and prevents static linking of all boost libraries.

This appears when attempting to static-link boost v1.58 into a project using MSVC-12.0, using the /MT /MTD runtime-options.

without knowing that BOOST_PYTHON_STATIC_LIB must be defined, this prevents the use of boost in this scenario.

Unless there is some reason why boost-python itself cannot be statically linked (which doesn't appear to be the case), this behavior is not only highly-problematic, but potentially breaking.

comment:13 by John Maddock, 7 years ago

Component: configPython
Owner: changed from John Maddock to Ralf W. Grosse-Kunstleve
Status: reopenednew

I don't have Python development files to test with, but if python.hpp is setting these macros then that's a bug.... as is dynamic linking when using the static runtime.

Reassigning.

Note: See TracTickets for help on using tickets.