[thread] Why is there a restriction for the runtime libraries?

There are two restrictions in the thread jamfile I don't understand: - the thread lib must be built with static runtime libraries - the thread dll must be built with dynamic runtime libraries What is the reason for that? Why can't I use the shared rt and link boost.thread statically (and vice versa)??? Stefan

Stefan Slapeta wrote:
There are two restrictions in the thread jamfile I don't understand:
- the thread lib must be built with static runtime libraries - the thread dll must be built with dynamic runtime libraries
What is the reason for that? Why can't I use the shared rt and link boost.thread statically (and vice versa)???
Have a look at the thread on the users list: Re: [Boost-users] Re: Memory leak reported using threads library Basically because: #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 and Peter Dimov wrote:
It works as long as you don' allocate in one and delete in the other. C-style interfaces are fine, but passing a std::string from the EXE to the DLL (or vice versa) will fail. shared_ptr will work, though :-) unless you unload the DLL that has created it, of course. Deleting an object with a virtual destructor works, too.
as the explanation of "bad idea". But perhaps this reasoning should be mad more explicit. At least as an extended comment in the autolink file as I already suggested. Roland

Roland Schwarz wrote:
Have a look at the thread on the users list:
Which thread?
Re: [Boost-users] Re: Memory leak reported using threads library
Basically because: #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
This doesn't explain why one shouldn't use a shared rt with the static boost.thread lib! [IMO there got some things mixed up.] IIRC the code above is only considered when there is no static TSS cleanup possible for a certain compiler, no?
and Peter Dimov wrote:
It works as long as you don' allocate in one and delete in the other. C-style interfaces are fine, but passing a std::string from the EXE to the DLL (or vice versa) will fail. shared_ptr will work, though :-) unless you unload the DLL that has created it, of course. Deleting an object with a virtual destructor works, too.
AFAIK this is a common (DLL) problem and not specific to the thread library. Stefan

Stefan Slapeta wrote:
This doesn't explain why one shouldn't use a shared rt with the static boost.thread lib! [IMO there got some things mixed up.]
Yes it seems so. I know no reason why a dynamic CRT could not be used with the static lib. There indeed seems something wrong. I recommend having Michael also have a look on it!
IIRC the code above is only considered when there is no static TSS cleanup possible for a certain compiler, no?
Hmm. As far as I remember the code is specific to MSVC, and the static TSS cleanup has been resolved. So in principle any MS compiler should now support it.
AFAIK this is a common (DLL) problem and not specific to the thread library.
Again yes. I misunderstood your original post. I vaguely remember havin tried to ask the question before. But perhaps I made my point not clear enough. Perhaps you can resolve the issue? I just tried to compile with having BOOST_THREAD_USE_LIB while selecting the dynamic RTL. (Which is exactly what you are refering too?) At link stage the compiler complains about: LINK : fatal error LNK1104: cannot open file 'libboost_thread-vc71-mt-gd-1_32.lib' So this obviously is because the bjam did not build it. Only libboost_thread-vc71-mt-sgd.lib is there. Altough I recommend to test it before enabling it. Roland

Roland Schwarz wrote:
[many things...]
There are two problems: one is in the jamfile, the other is in boost configuration. Both together make it impossible to configure boost.thread for a dynamic rt! a) thread/build/jamfile: remove the requirements for the runtime. b) thread/detail/config.hpp: # if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) //For VC++, choose according to threading library setting # if defined(_DLL) //Threading library is dll: use Boost.Threads dll # define BOOST_THREAD_USE_DLL # define BOOST_THREAD_DECL __declspec(dllimport) # define BOOST_DYN_LINK # else //Threading library is lib: used Boost.Threads lib # define BOOST_THREAD_USE_LIB # define BOOST_THREAD_DECL # endif # else IMO this sequence is wrong (look at the comments!) because the _DLL macro _DOESN'T_ say that a dll is built!!!! It rather says that a shared runtime is used (I don't know if this was the intention behind this sequence, the comment is wrong anyway). The code as is means that every static rt configuration is linked to a static boost.thread lib and every dynamic rt configuration is linked to boost.thread as dll. I just don't know if there is any rationale behind automatically selecting these combinations. Stefan

Stefan Slapeta wrote:
b)
thread/detail/config.hpp:
# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) //For VC++, choose according to threading library setting # if defined(_DLL) //Threading library is dll: use Boost.Threads dll # define BOOST_THREAD_USE_DLL # define BOOST_THREAD_DECL __declspec(dllimport) # define BOOST_DYN_LINK # else //Threading library is lib: used Boost.Threads lib # define BOOST_THREAD_USE_LIB # define BOOST_THREAD_DECL # endif # else
IMO this sequence is wrong (look at the comments!) because the _DLL macro _DOESN'T_ say that a dll is built!!!! It rather says that a shared runtime is used (I don't know if this was the intention behind this sequence, the comment is wrong anyway). The code as is means that every static rt configuration is linked to a static boost.thread lib and every dynamic rt configuration is linked to boost.thread as dll. I just don't know if there is any rationale behind automatically selecting these combinations.
I think the problem is of how to deduce how the boost libs should be linked in when the user does not explicitely specifiy e.g. BOOST_USE_LIB. A reasonable default in this case would be then to link in the library corresponding to the RTL choice. The code snippet refers to the default choice doesn't it? # else //Use default The comment //For VC++, choose according to threading library setting should better read //For VC++, choose according to C-runtime library setting of course. Does this make sense? Roland

Roland Schwarz wrote:
I think the problem is of how to deduce how the boost libs should be linked in when the user does not explicitely specifiy e.g. BOOST_USE_LIB. A reasonable default in this case would be then to link in the library corresponding to the RTL choice.
I don't know if this is reasonable but it's different from what other boost libraries do (which _always_ default to linking the corresponding static boost lib). If there is a rational behind that, it should be documented!
The code snippet refers to the default choice doesn't it? # else //Use default The comment //For VC++, choose according to threading library setting should better read //For VC++, choose according to C-runtime library setting of course.
Does this make sense?
yes, if the behaviour remains unchanged, this should be fixed. Anyway, IMO it's a clear bug in the jamfile that the boost.thread libraries for the static rt configuration are not built! Stefan

Stefan Slapeta wrote:
I don't know if this is reasonable but it's different from what other boost libraries do (which _always_ default to linking the corresponding static boost lib). If there is a rational behind that, it should be documented!
Then I think it is better to do the same as the other libs. Anything else would confuse users.
The code snippet refers to the default choice doesn't it? # else //Use default The comment //For VC++, choose according to threading library setting should better read //For VC++, choose according to C-runtime library setting of course.
Does this make sense?
yes, if the behaviour remains unchanged, this should be fixed.
I also think so.
Anyway, IMO it's a clear bug in the jamfile that the boost.thread libraries for the static rt configuration are not built!
Is this a typo? libboost_thread-vc71-mt-sgd.lib is built (this is the static crt version) while libboost_thread-vc71-mt-gd.lib is missing. (And the non debug versions accordingly.) Roland

"Stefan Slapeta" <stefan@slapeta.com> wrote in message news:cp1nnh$mli$1@sea.gmane.org...
Roland Schwarz wrote:
I think the problem is of how to deduce how the boost libs should be linked in when the user does not explicitely specifiy e.g. BOOST_USE_LIB. A reasonable default in this case would be then to link in the library corresponding to the RTL choice.
I don't know if this is reasonable but it's different from what other boost libraries do (which _always_ default to linking the corresponding static boost lib). If there is a rational behind that, it should be documented!
The code snippet refers to the default choice doesn't it? # else //Use default The comment //For VC++, choose according to threading library setting should better read //For VC++, choose according to C-runtime library setting of course.
Does this make sense?
yes, if the behaviour remains unchanged, this should be fixed.
Anyway, IMO it's a clear bug in the jamfile that the boost.thread libraries for the [dynamic] rt configuration are not built!
Perhaps I missed something, but did you determine why it isn't being built? I'm not able to run a build at the moment so I can't test it myself right now. Earlier in this discussion the problem of the Boost.Threads dll requiring the C RTL dll and the Boost.Threads lib requiring the C RTL lib, but does that problem relate to this one? Also, I'm far from being a jamfile wiz, so if you could suggest specific changes to illustrate what you think it should be, I'd appreciate it. Mike

Michael Glassford wrote:
Perhaps I missed something, but did you determine why it isn't being built?
Yes, this was the reason for my original posting. If there are no objections, I'll commit these changes. I'm sure the restrictions below just exist for historical reasons (I can't explain either why e.g. a static boost.thread library shouldn't use a dynamic rt). diff -u -r1.34 Jamfile --- Jamfile 19 Aug 2004 19:27:15 -0000 1.34 +++ Jamfile 6 Dec 2004 20:43:47 -0000 @@ -46,7 +46,6 @@ : ## requirements ## <sysinclude>$(BOOST_ROOT) #:should be unnecessary (because already included in thread_base) <define>BOOST_THREAD_BUILD_LIB=1 - <runtime-link>static # the common names rule ensures that the library will # be named according to the rules used by the install # and auto-link features: @@ -61,7 +60,6 @@ : ## requirements ## <sysinclude>$(BOOST_ROOT) #:should be unnecessary (because already included in thread_base) <define>BOOST_THREAD_BUILD_DLL=1 - <runtime-link>dynamic # the common names rule ensures that the library will # be named according to the rules used by the install # and auto-link features:

Stefan Slapeta wrote:
Michael Glassford wrote:
Perhaps I missed something, but did you determine why it isn't being built?
Yes, this was the reason for my original posting. If there are no objections, I'll commit these changes. I'm sure the restrictions below just exist for historical reasons (I can't explain either why e.g. a static boost.thread library shouldn't use a dynamic rt).
Despite the fact that other Boost libs have their static libs use a dynamic RTL there is a reason to do otherwise. Many programmers have historically wanted to build a single executable without any shared libraries for their application. This can be done if the static libs used by that executable all use the static RTL. Once one of those static libs uses the dynamic RTL it is no longer possible to do this, and there is no way, using such a library, to build a single executable that can be distributed without any shared libraries. I do not so much mind that other people disagree with me about having static libs use the static RTL and shared libs ( dlls on Windows ) use the dynamic RTL, but I do mind it when others can not understand the simple argument, whether agreed with or not, I have just specified as a reason for doing so. Of course if Boost does not feel that they have to cater to those wishing to build a single executable without any shared libraries, that is fine with me. I just want to point out that if the default situation is to have static libs use the static RTL and shared libs use the dynamic RTL, developers can get the best of both worlds; either a single monolithic executable or an executable where all libraries are shared, depending on whether they choose to use static libs or shared libs when building their application.

Edward Diener wrote:
Stefan Slapeta wrote:
Michael Glassford wrote:
Perhaps I missed something, but did you determine why it isn't being built?
Yes, this was the reason for my original posting. If there are no objections, I'll commit these changes. I'm sure the restrictions below just exist for historical reasons (I can't explain either why e.g. a static boost.thread library shouldn't use a dynamic rt).
Despite the fact that other Boost libs have their static libs use a dynamic RTL there is a reason to do otherwise. Many programmers have historically wanted to build a single executable without any shared libraries for their application. This can be done if the static libs used by that executable all use the static RTL. Once one of those static libs uses the dynamic RTL it is no longer possible to do this, and there is no way, using such a library, to build a single executable that can be distributed without any shared libraries.
I am not sure about what exactly you are talking, so I try to clarify: 1) MyApp using static runtime. a) MyApp using static boost lib --> link in: libboost_thread-*-mt-s??-1_32.lib b) MyApp using dynamic boost lib --> probably not a good idea 2) MyApp using dynamic runtime: a) My App using static boost lib --> link in: libboost_thread-*-mt-??-1_32.lib b) MyApp using dynamic boost lib --> link in: boost_thread-*-mt-??-1_32.lib As you can see 1a) is your requested case. But nothing should prevent a user to choose 2a) if she decides. The original observation was that case 2a) isn't currently available. I don't think you are advocationg for not allowing for case 2a) aren't you? BTW.: Only case 1b) will result in using two instances of the RTL lib which is considered bad.
I do not so much mind that other people disagree with me about having static libs use the static RTL and shared libs ( dlls on Windows ) use the dynamic RTL, but I do mind it when others can not understand the simple argument, whether agreed with or not, I have just specified as a reason for doing so.
Most of the recent effort has been to restore exactly what you want. In 1-31 only case 2b) was available with full features.
Of course if Boost does not feel that they have to cater to those wishing to build a single executable without any shared libraries, that is fine with me. I just want to point out that if the default situation is to have static libs use the static RTL and shared libs use the dynamic RTL, developers can get the best of both worlds; either a single monolithic executable or an executable where all libraries are shared, depending on whether they choose to use static libs or shared libs when building their application.
Now they even have a third option too (2a). The whole issue is not about taking away options but to add missing ones. The only question was what are the defaults: When user chooses 1) --> default is 1a) When user chooses 2) --> default is 2a) (altough I would rather like 2b, but this I have been told is against boost standards) Roland

Roland Schwarz wrote:
[...]
Now they even have a third option too (2a). The whole issue is not about taking away options but to add missing ones. The only question was what are the defaults: When user chooses 1) --> default is 1a) When user chooses 2) --> default is 2a) (altough I would rather like 2b, but this I have been told is against boost standards)
Thanks for the correct analysis! Stefan

I thought I had sent this yesterday, but I guess not... "Stefan Slapeta" <stefan@slapeta.com> wrote in message news:cp2gld$7r8$1@sea.gmane.org...
Michael Glassford wrote:
Perhaps I missed something, but did you determine why it isn't being built?
Yes, this was the reason for my original posting. If there are no objections, I'll commit these changes. I'm sure the restrictions below just exist for historical reasons (I can't explain either why e.g. a static boost.thread library shouldn't use a dynamic rt).
diff -u -r1.34 Jamfile --- Jamfile 19 Aug 2004 19:27:15 -0000 1.34 +++ Jamfile 6 Dec 2004 20:43:47 -0000 @@ -46,7 +46,6 @@ : ## requirements ## <sysinclude>$(BOOST_ROOT) #:should be unnecessary (because already included in thread_base) <define>BOOST_THREAD_BUILD_LIB=1 - <runtime-link>static # the common names rule ensures that the library will # be named according to the rules used by the install # and auto-link features: @@ -61,7 +60,6 @@ : ## requirements ## <sysinclude>$(BOOST_ROOT) #:should be unnecessary (because already included in thread_base) <define>BOOST_THREAD_BUILD_DLL=1 - <runtime-link>dynamic # the common names rule ensures that the library will # be named according to the rules used by the install # and auto-link features:
Wouldn't this have the opposite problem of not allowing a static boost.threads library to link to a static rtl? Or am I misunderstanding the <runtime-link> option? Mike

Michael Glassford wrote:
Wouldn't this have the opposite problem of not allowing a static boost.threads library to link to a static rtl? Or am I misunderstanding the <runtime-link> option?
---> : ## requirements ## :) Stefan

"Roland Schwarz" <roland.schwarz@chello.at> wrote in message news:41B45B95.8020909@chello.at...
Stefan Slapeta wrote:
b)
thread/detail/config.hpp:
# if defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN) //For VC++, choose according to threading library setting # if defined(_DLL) //Threading library is dll: use Boost.Threads dll # define BOOST_THREAD_USE_DLL # define BOOST_THREAD_DECL __declspec(dllimport) # define BOOST_DYN_LINK # else //Threading library is lib: used Boost.Threads lib # define BOOST_THREAD_USE_LIB # define BOOST_THREAD_DECL # endif # else
IMO this sequence is wrong (look at the comments!) because the _DLL macro _DOESN'T_ say that a dll is built!!!! It rather says that a shared runtime is used (I don't know if this was the intention behind this sequence, the comment is wrong anyway).
Depends how you read the comment. By "threading library" above I meant the VC++ threading library, part of the VC++ runtime library. I can certainly change the comments (as suggested below) to make this clearer.
The code as is means that every static rt configuration is linked to a static boost.thread lib and every dynamic rt configuration is linked to boost.thread as dll. I just don't know if there is any rationale behind automatically selecting these combinations.
I think the problem is of how to deduce how the boost libs should be linked in when the user does not explicitely specifiy e.g. BOOST_USE_LIB. A reasonable default in this case would be then to link in the library corresponding to the RTL choice.
This was my intention when I wrote the above.
The code snippet refers to the default choice doesn't it?
Yes, it chooses a default that can be overridden by #defining BOOST_THREAD_USE_LIB or BOOST_THREAD_USE_DLL
# else //Use default The comment //For VC++, choose according to threading library setting should better read //For VC++, choose according to C-runtime library setting of course.
Does this make sense?
Roland
Yes. Mike

Michael Glassford wrote:
I think the problem is of how to deduce how the boost libs should be linked in when the user does not explicitely specifiy e.g. BOOST_USE_LIB. A reasonable default in this case would be then to link in the library corresponding to the RTL choice.
This was my intention when I wrote the above.
Why? I don't see any context between a shared rt and dynamic boost library. boost.thread shows a different behaviour than other boost libraries (which always default to link the static boost lib). Stefan

"Stefan Slapeta" <stefan@slapeta.com> wrote in message news:cp2gsl$8gl$1@sea.gmane.org...
Michael Glassford wrote:
I think the problem is of how to deduce how the boost libs should be linked in when the user does not explicitely specifiy e.g. BOOST_USE_LIB. A reasonable default in this case would be then to link in the library corresponding to the RTL choice.
This was my intention when I wrote the above.
Why? I don't see any context between a shared rt and dynamic boost library. boost.thread shows a different behaviour than other boost libraries (which always default to link the static boost lib).
It seemed to me at the time that if the user didn't specify explicit linking options for Boost.Threads, the most sensible default options were a) everything in a separate dll (dynamically linked), or b) everything in one exe (statically linked). In retrospect, perhaps this was incorrect. Mike

Michael Glassford wrote:
"Stefan Slapeta" <stefan@slapeta.com> wrote in message news:cp2gsl$8gl$1@sea.gmane.org...
Michael Glassford wrote:
I think the problem is of how to deduce how the boost libs should be linked in when the user does not explicitely specifiy e.g. BOOST_USE_LIB. A reasonable default in this case would be then to link in the library corresponding to the RTL choice.
This was my intention when I wrote the above.
Why? I don't see any context between a shared rt and dynamic boost library. boost.thread shows a different behaviour than other boost libraries (which always default to link the static boost lib).
It seemed to me at the time that if the user didn't specify explicit linking options for Boost.Threads, the most sensible default options were a) everything in a separate dll (dynamically linked), or b) everything in one exe (statically linked). In retrospect, perhaps this was incorrect.
I think it is correct but Boost does not follow this pattern by default. I have discussed this with John Maddock but evidently he feels that the default when linking with the dynamic RTL is to use the library's static library rather than the dynamic one. There are macros to force the use of the dynamic one instead, BOOST_ALL_DYN_LINK and BOOST_..._DYN_LINK, as well as macros that turn off auto-linking, BOOST_ALL_NO_LIB and BOOST_..._NO_LIB.
participants (5)
-
Edward Diener
-
Michael Glassford
-
Roland Schwarz
-
Stefan Slapeta
-
Stefan Slapeta