Friday 29 April 2011

Developer Journal 78 - On Boost Serialization

I finally worked out how to build Boost 1.44 Serialization with MinGW.

I found the solution by doing a Google search for "Boost 1.44 Serialization undefined reference".


Jim Bell, found out that the flag BOOST_SERIALIZATION_SOURCE was missing somewhere. The contributor suggested adding BOOST_SERIALIZATION_SOURCE 1 to the Jamfile. Unfortunately, the change was only incorporated in the next version of Boost which was 1.45 and not 1.44.

I changed the D:/agi/dep/boost_1_44_0/libs/serialization/build/Jamfile.v2 from,

project boost/serialization
    : source-location ../src
    : requirements
      <conditional>@include-spirit
;

to,

project boost/serialization
    : source-location ../src
    : requirements
      <conditional>@include-spirit
 <define>BOOST_SERIALIZATION_SOURCE=1
;

I compiled but I got the same error messages.

bin.v2\libs\serialization\build\gcc-mingw-4.5.0\debug\threading-multi\basic_iarchive.o:D:\agi\dep\boost_1_44_0/./boost/archive/detail/basic_serializer.hpp:54: undefined reference to `_imp___
ZNK5boost13serialization18extended_type_infoltERKS1_'

bin.v2\libs\serialization\build\gcc-mingw-4.5.0\debug\threading-multi\basic_iarchive.o:D:\agi\dep\boost_1_44_0/libs/serialization/src/basic_iarchive.cpp:426: undefined reference to `_imp___Z
N5boost13serialization18extended_type_info4findEPKc'

bin.v2\libs\serialization\build\gcc-mingw-4.5.0\debug\threading-multi\shared_ptr_helper.o:D:\agi\dep\boost_1_44_0/libs/serialization/src/shared_ptr_helper.cpp:50: undefined reference to `_im
p___ZN5boost13serialization13void_downcastERKNS0_18extended_type_infoES3_PKv'

bin.v2\libs\serialization\build\gcc-mingw-4.5.0\debug\threading-multi\shared_ptr_helper.o:D:\agi\dep\boost_1_44_0/libs/serialization/src/shared_ptr_helper.cpp:76: undefined reference to `_im
p___ZN5boost13serialization11void_upcastERKNS0_18extended_type_infoES3_PKv



BJam was not re-compiling because the source files had not changed, only the Jamfile.

I tried using different configurations of BJam clean but I could not get BJam to do a clean.

bjam --clean

bjam --clean-all



I went in and removed the following directory which contained the .o files.

  • D:\agi\dep\boost_1_44_0\bin.v2\libs\serialization

I then removed the following directory which contained the library file.

  • D:\agi\dep\boost_1_44_0\stage\lib

I then re-compiled and building Boost 1.44 Serialization dynamic link libraries worked this time.



I wanted to be able to make changes in BJam and to re-compile without having to manually remove files. I looked around and found the BJam flag, "-a", to force a re-compile.

Usage:

bjam [options] [properties] [install|stage]

Important Options:

-a    Rebuild everything

Other Options:

--help    This message.



The solution worked but it's not elegant so I'm going to work for a while on it. The modification to the Jamfile adds the flag everywhere. I want to see if I can add the flag in the right place to overcome the undefined reference errors.

I did a search for mention of BOOST_SERIALIZATION_SOURCE.

  • grep -nH -r -i -e BOOST_SERIALIZATION_SOURCE d:/agi/dep/boost_1_44_0

d:/agi/dep/boost_1_44_0/boost/archive/detail/auto_link_archive.hpp:30:&&  !defined(BOOST_SERIALIZATION_SOURCE)

d:/agi/dep/boost_1_44_0/boost/serialization/config.hpp:41:    #if defined(BOOST_SERIALIZATION_SOURCE)

d:/agi/dep/boost_1_44_0/boost/serialization/config.hpp:53:    #endif // defined(BOOST_SERIALIZATION_SOURCE)

d:/agi/dep/boost_1_44_0/boost/serialization/config.hpp:66:&&  !defined(BOOST_SERIALIZATION_SOURCE)

d:/agi/dep/boost_1_44_0/libs/serialization/src/extended_type_info.cpp:32:#define BOOST_SERIALIZATION_SOURCE

d:/agi/dep/boost_1_44_0/libs/serialization/src/extended_type_info_no_rtti.cpp:21:#define BOOST_SERIALIZATION_SOURCE

d:/agi/dep/boost_1_44_0/libs/serialization/src/extended_type_info_typeid.cpp:22:#define BOOST_SERIALIZATION_SOURCE

d:/agi/dep/boost_1_44_0/libs/serialization/src/void_cast.cpp:29:#define BOOST_SERIALIZATION_SOURCE

The only places where BOOST_SERIALIZATION_SOURCE is used in a selection statement are in auto_link_archive.hpp and config.hpp.

I'm not sure what to do with that so in the .cpp files I'm going to change from

BOOST_SERIALIZATION_SOURCE

to,

BOOST_SERIALIZATION_SOURCE 1

No success.

I'm going to add a #define BOOST_SERIALIZATION_SOURCE before each selection statement in the header files.

Success!



Fix 1

In, d:/agi/dep/boost_1_44_0/boost/archive/detail/auto_link_archive.hpp, I added #define BOOST_SERIALIZATION_SOURCE.

#define BOOST_SERIALIZATION_SOURCE

#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_SERIALIZATION_NO_LIB) \
&&  !defined(BOOST_ARCHIVE_SOURCE) && !defined(BOOST_WARCHIVE_SOURCE)  \
&&  !defined(BOOST_SERIALIZATION_SOURCE)

Fix 2

In d:/agi/dep/boost_1_44_0/boost/serialization/config.hpp, I added #define BOOST_SERIALIZATION_SOURCE.

#define BOOST_SERIALIZATION_SOURCE
    #if defined(BOOST_SERIALIZATION_SOURCE)
        #if defined(__BORLANDC__)
            #define BOOST_SERIALIZATION_DECL(T) T __export
        #else
            #define BOOST_SERIALIZATION_DECL(T) __declspec(dllexport) T
        #endif
    #else
        #if defined(__BORLANDC__)
            #define BOOST_SERIALIZATION_DECL(T) T __import
        #else
            #define BOOST_SERIALIZATION_DECL(T) __declspec(dllimport) T
        #endif
    #endif // defined(BOOST_SERIALIZATION_SOURCE)



Looking back, changing the Jamfile.v2 was probably the easier and better option.

At least now I don't have to go into the process of re-compiling Ogre 1.7.2.

I noticed that the version of MinGW I got from Twilight Dragon Media was actually 4.5.

I'm not sure whether Ogre 1.7.2 requires the Boost 1.44 files to be built with MinGW 4.4. I'm going to test that out now.

Success. MinGW 4.5 works.



Now I'm going to re-enable serialization in my code.

Success. The simulation compiled and ran!



The following is a warning message I've wanted to fix for a long time.

In file included from D:\agi\dep\boost_1_44_0/boost/thread/detail/thread_heap_alloc.hpp:15:0,
                 from D:\agi\dep\boost_1_44_0/boost/thread/tss.hpp:10,
                 from D:\agi\dep\ogre\include/OGRE/Threading/OgreThreadHeadersBoost.h:29,
                 from D:\agi\dep\ogre\include/OGRE/Threading/OgreThreadHeaders.h:30,
                 from D:\agi\dep\ogre\include/OGRE/OgreStdHeaders.h:110,
                 from D:\agi\dep\ogre\include/OGRE/OgrePrerequisites.h:315,
                 from D:\agi\dep\ogre\include/OGRE/OgreException.h:32,
                 from D:\agi\polyworld\app\main.cpp:2:
D:\agi\dep\boost_1_44_0/boost/thread/win32/thread_heap_alloc.hpp:59:40: warning: inline function 'void* boost::detail::allocate_raw_heap_memory(unsigned int)' declared as  dllimport: attribute ignored
D:\agi\dep\boost_1_44_0/boost/thread/win32/thread_heap_alloc.hpp:69:39: warning: inline function 'void boost::detail::free_raw_heap_memory(void*)' declared as  dllimport: attribute ignored

In d:/dep/boost_1_44_0/boost/thread/win32/thread_heap_alloc.hpp I changed,

inline BOOST_THREAD_DECL void* allocate_raw_heap_memory(unsigned size)
inline BOOST_THREAD_DECL void free_raw_heap_memory(void* heap_memory)

to

inline void* allocate_raw_heap_memory(unsigned size)
inline void free_raw_heap_memory(void* heap_memory)



I'd love to figure out how to build Boost without the "w" variant.

Time to do a little serializing. An interesting thing I noticed was that the compile and link times are not significantly much longer with serialization enabled. The compile and link times were very long when I was writing Makefiles by hand, adding up to an additional five minutes.

I'm not sure whether the build times are quick because I'm using CMake instead of manually writing Makefiles or because I've only got a little of the serialization, template, and macro code enabled.

Grr. I originally had a console where I could enter commands but I had to disable it when I changed to Ogre.

So far so good. I'm re-enabling serialization for objects one at a time.



RELATED

No comments:

Post a Comment