Search code examples
c++boostlinker-errorsmultiple-definition-error

Boost - Multiple definitions during linking


I have these two classes (let's call them A and B) that both include boost/archive and boost/serialization files. These includes are in my hpp files (with header guards) for each of the two classes. Class A (and other parts of the code base) include class B and as such repeats the exact same includes.

From my understanding the header guards in the boost library should be preventing the library files from being included a second time here; but that appears not to be the case. I have even gone as far as putting another header guard around the include bloc just to make sure it wouldn't be included multiple times; and yet at linkage I get a multiple definition's error.

Includes in class A:

#ifndef _A_H
#define _A_H


// Other none boost includes for class A
#ifndef _BOOST_INCLUDES_
#define _BOOST_INCLUDES_
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/access.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/string.hpp>
#endif

class A{/*...*/};

And class B has the same include block (and _BOOST_INCLUDES_ guard) in its header file. Other parts of the code also include class A or class B at some point, but the problem stems from something in the includes here.

Why is this happening (and how could I fix it)? Why aren't the boost header guards stopping this second inclusion? Could this have nothing to do with the code itself but rather be a build problem?

Makefile extract:

BOOST_ROOT  := myPathToBoost/boost_1_75_0/
BOOST_LIBS  := -L$(BOOST_ROOT)stage/lib/ -lboost_serialization
BOOST       := -I $(BOOST_ROOT) $(BOOST_LIBS)

$(CM_OBJS): $(CM_SOURCES)
    $(CC) $(FLAGS) -MMD $(BOOST) -c $(INCLUDES) -o $@ $< $(LIBS)

The linker error is:

/usr/bin/ld: /projectPath/build/clientMain.o:(.bss+0x0): multiple definition of `boost::archive::detail::extra_detail::init_guid<EndGame>::g'; /projectPath/build/Register.o:(.bss+0x0): first defined here

And this message repeats for every include; with the file names varying, and the contents of ::init_guid<X> varying as well.


Solution

  • Indeed putting BOOST_CLASS_EXPORT in a header file leads to multiply defined symbols as soon as you have included the header file into more than one translation unit (think .cpp file).

    In absence of your code, I have many full examples on this site. I'd search like "user:85371 boost_class_export_key":

    Most of them have multi-file live demos online and included in the answer text.