Opened 12 years ago

Closed 12 years ago

Last modified 12 years ago

#4959 closed Bugs (invalid)

Linking Serialization static lib to a DLL breaks auto-import in MinGW

Reported by: jlcastillo@… Owned by: Robert Ramey
Milestone: To Be Determined Component: serialization
Version: Boost 1.45.0 Severity: Problem
Keywords: Cc:

Description

With MinGW GCC 4.51 and Boost 1.45, boost being compiled with the following command line:

bjam toolset=gcc --build-type=complete --threading=multi variant=release link=static runtime-link=shared stage --stagedir=$RELEASE_LIB_DIR -j2
bjam toolset=gcc --build-type=complete --threading=multi variant=debug link=static runtime-link=shared stage --stagedir=$DEBUG_LIB_DIR -j2

The static serialization lib attaches "declspec(dllexport)" to some methods in boost/serialization/singleton.hpp, i.e. get_mutable_instance, get_const_instance and is_destroyed.

This is OK if we link the static library against an executable. If we however link it against a DLL, GCC stops exporting automatically all the symbols in the source code of the DLL (auto-import feature), and switches to a linking mode where only those functions declared with "declspec(dllexport)" are exported.

This is very inconvenient and hard to track if you use an automatic build environment like Boost Build (bjam).

We fixed it adding the following lines to /boost/serialization/force_include.hpp:

#if defined(BOOST_HAS_DECLSPEC) && !defined(__COMO__)
#   if defined(__BORLANDC__)
#       define BOOST_DLLEXPORT __export
#   elif defined(__MINGW32__)   // JOSE FIX !!!!
#     if defined(__GNUC__) && (__GNUC__ >= 3)
#        define BOOST_USED __attribute__ ((used))
#     endif
#   else
#       define BOOST_DLLEXPORT __declspec(dllexport)
#   endif
#elif ! defined(_WIN32) && ! defined(_WIN64)
#   if defined(__MWERKS__)
#       define BOOST_DLLEXPORT __declspec(dllexport)
#   elif defined(__GNUC__) && (__GNUC__ >= 3)
#       define BOOST_USED __attribute__ ((used))
#   elif defined(???????) && (?????? >= 1110)
#       define BOOST_USED __attribute__ ((used))
#   elif defined(__INTEL_COMPILER) && (BOOST_INTEL_CXX_VERSION >= 800)
#       define BOOST_USED __attribute__ ((used))
#   endif
#endif

You need to recompile the Boost Serialization static library with these changes, and make sure you have the modified force_include.hpp in the boost include that your apps use during compilation.

Change History (2)

comment:1 by Robert Ramey, 12 years ago

Resolution: invalid
Status: newclosed

this needs more analysis

a) what is ??????? ? b) JOSE FIX line will break normal gcc compilations

Is one using "visibility" in the command line options?

I believe that what is necessary is that the "force include" functionality be suppressed for builds of the library version of the DLLS.

I realize that this is a problem, but I don't see enough information here to be able to address it.

BTW - doesn't the definition of MINGW32 imply the definition of GNUC ? so I can't see how the suggested fix would change anything.

Robert Ramey

in reply to:  1 comment:2 by jlcastillo@…, 12 years ago

I realize my explanation may lead to misunderstanding. I'll try to elaborate it further.

a) "????????" was addded in replacement of the original text, because WikiFormatting complained about it (it seems there is some "intelligent" engine that rejects some words). It doesn't have any importance, just ignore it, you don't need to change those lines in the original file.

b) The following lines are not present in the original /boost/serialization/force_include.hpp, and should be included:

#   elif defined(__MINGW32__)
#     if defined(__GNUC__) && (__GNUC__ >= 3)
#        define BOOST_USED __attribute__ ((used))
#     endif

As you state, we can possibly omit "defined(GNUC)", as it could be implicitly defined along with MINGW32. I left it just to keep the same structure that I saw below. I guess "(GNUC >= 3)" should remain.

Note: See TracTickets for help on using tickets.