Hugh Hoover wrote:
On Feb 27, 2006, at 08:51, Robert Ramey wrote:
*** Hmmm - I'll look into this. I would have expected that additional code would be generated if and only if
// if no archive headers have been included this is a no op // this is to permit BOOST_EXPORT etc to be included in a // file declaration header #if ! defined(BOOST_ARCHIVE_BASIC_ARCHIVE_HPP) #define BOOST_CLASS_EXPORT_GUID_ARCHIVE_LIST(T, K, ASEQ)
which I would expect would make a BOOST_EXPORT an effective no-op if no archive files are included.
I'll chime in, as I'm having exactly the same issue, but on darwin/ gcc-4 with code in multiple dynamically loaded libraries... (I have other issues too, I get to those later)
The problem is that although export.hpp is only included once per generated .o file, there are multiple .o files all including the same headers - and each therefore generates the same template instantiations, thereby causing the multiple definitions during linking. Also - the same headers may be included in multiple shared libraries, exacerbating the problem with the same code instantiated into multiple libraries - a serious problem if there are singletons.
I may not be understanding this correctly - here's what >I< think needs to happen - please correct me.
For any derived class, there is a set of code (templates) that need to be instantiated for each archive type (specifically, the list boost::archive::detail::known_archive_types::type, for the templates guid_initializer<T> and export_instantiate
) From what I see, these are NOT declarations required by the other serialization code, but singletons that, during construction, register the serializers to the derived classes with the extended_type_info class registry. Is that incorrect? If the above is correct, then the BOOST_EXPORT_CLASS should only be in exactly one implementation file (.cpp, .C, .cc, whatever). And also, THAT implementation file should ONLY be linked into one shared library.
Not quite. There should be only one source module which includes boost/archive/... declarations. If there is more than one of these then there is a risk of multiple definitions. My practice is to: a) include all boost/serialization/.. headers in each class file. b) include NO boost/archive/... headers in any class file c) make a "template instantiation module" which instanticiates code for all archives I plan to use. This can be either in the app or in a library. d) lihk and execute without problem. Robert Ramey