On 7/28/2015 8:49 AM, Ruben Van Boxem wrote:
> 2015-07-28 14:44 GMT+02:00 Edward Diener <[email protected]
> <mailto:[email protected]>>:
>
>     On 7/28/2015 8:27 AM, Edward Diener wrote:
>      > Without trying immediately to give specific code for what is a large
>      > project, I am getting linker errors when trying to link a second
>     shared
>      > library which depends on a first shared library that has linked
>      > successfully. The errors are:
>      >
>      >
>     
> xml_wgrammar.o:xml_wgrammar.cpp:(.rdata$_ZTVN5boost7archive21xml_archive_exceptionE[__ZTVN5boost7archive21xml_archive_exceptionE]+0x20):
>      > undefined reference to `virtual thunk to
>      > boost::archive::archive_exception::what() const'
>      >
>     
> xml_wgrammar.o:xml_wgrammar.cpp:(.rdata$_ZTCN5boost7archive21xml_archive_exceptionE4_NS0_17archive_exceptionE[__ZTCN5boost7archive21xml_archive_exceptionE4_NS0_17archive_exceptionE]+0x38):
>      > undefined reference to `virtual thunk to
>      > boost::archive::archive_exception::what() const'
>      > collect2.exe: error: ld returned 1 exit status
>      >
>      > The xml_wgrammar.o file is being linked into the second shared
>     library.
>      > The xml_wgrammar.cpp file includes xml_archive_exception.hpp. The
>      > xml_archive_exception.hpp includes and derives from
>      > archive_exception.hpp. Both xml_archive_exception and
>     archive_exception
>      > have their implementation in the first shared library and have their
>      > necessary implementations exported. The implementation of
>      > archive_exception::what() is exported in the first shared library
>     and is
>      > imported when seen by xml_wgrammar.cpp.
>      >
>      > What is so strange is that there is no call to
>     archive_exception::what()
>      > in the preprocessed output of xml_wgrammar.cpp.
>      >
>      > Does anybody have any idea what might be going on here before I
>     take the
>      > time to reduce this situation into a short enough fragment to
>     show in a
>      > subsequent thread in this post ?
>
>     After adding an xml_archive_exception::what() implementation which just
>     calls its base class archive_exception::what() implementation I now
>     receive the linker errors:
>
>     xml_wgrammar.o: In function
>     `ZN5boost7archive21xml_archive_exceptionD1Ev':
>     xml_archive_exception.hpp:34: undefined reference to `vtable for
>     boost::archive::xml_archive_exception'
>     xml_archive_exception.hpp:34: undefined reference to `vtable for
>     boost::archive::xml_archive_exception'
>     xml_archive_exception.hpp:34: undefined reference to `vtable for
>     boost::archive::xml_archive_exception'
>     xml_archive_exception.hpp:34: undefined reference to `VTT for
>     boost::archive::xml_archive_exception'
>     collect2.exe: error: ld returned 1 exit status
>
>     Perhaps this will give someone an idea of what might be happening.
>
>
> You're not linking to the boost_serialization library. At least on my
> system (Linux) boost::archive::{xml_,}archive_exception::what() is
> defined there.
>
> Add "-lboost_serialization" to your linker command or do the same
> through your build system.
> Note that Boost has #pragma lib ... to tell MSVC to link the required
> libraries. GCC does not have such a functionality.

Here are simplified files to reproduce the problem.

// ex_decl.hpp

#ifndef EX_DECL_HPP
#define EX_DECL_HPP

#if defined(BLD_EX_EXAMPLE)
        #define EX_DECL __attribute__((__dllexport__))
#else
        #define EX_DECL __attribute__((__dllimport__))
#endif

#define EX_VISIBLE __attribute__((__visibility__("default")))

#endif // EX_DECL_HPP

// ex_exception.hpp

#ifndef EX_EXCEPTION_HPP
#define EX_EXCEPTION_HPP

#include <exception>
#include "ex_decl.hpp"

class EX_VISIBLE ex_exception :
     public virtual std::exception
{
private:
     char m_buffer[128];
protected:
     EX_DECL unsigned int
     append(unsigned int l, const char * a);
     EX_DECL
     ex_exception() ;
public:
     typedef enum {
         no_exception,      // initialized without code
         other_exception    // any excepton not listed below
     } ex_exception_code;
     ex_exception_code code;

     EX_DECL ex_exception(
         ex_exception_code c,
         const char * e1 = 0,
         const char * e2 = 0
     ) ;
     EX_DECL ex_exception(ex_exception const &) ;
     virtual EX_DECL ~ex_exception() throw() ;
     virtual EX_DECL const char * what() const throw() ;
};

#endif // EX_EXCEPTION_HPP

// ex_exception.cpp

#include <exception>
#include <cstring>

#define BLD_EX_EXAMPLE
#include "ex_exception.hpp"

EX_DECL unsigned int ex_exception::append(unsigned int l, const char * a){
     while(l < (sizeof(m_buffer) - 1)){
         char c = *a++;
         if('\0' == c)
             break;
         m_buffer[l++] = c;
     }
     m_buffer[l] = '\0';
     return l;
}

EX_DECL ex_exception::ex_exception(ex_exception_code c,const char * 
e1,const char * e2) :
     code(c)
{
     unsigned int length = 0;
     switch(code){
     case no_exception:
         length = append(length, "uninitialized exception");
         break;
     case other_exception:
         // if get here - it indicates a derived exception
         // was sliced by passing by value in catch
         length = append(length, "unknown derived exception");
         break;
     default:
         length = append(length, "programming error");
         break;
     }
}

EX_DECL ex_exception::ex_exception(ex_exception const & oth) :
        std::exception(oth),
        code(oth.code)
{
        std::memcpy(m_buffer,oth.m_buffer,sizeof m_buffer);
}

EX_DECL ex_exception::~ex_exception() throw() {}

EX_DECL const char * ex_exception::what() const throw() {
      return m_buffer;
}

EX_DECL> ex_exception::ex_exception() :
     code(no_exception)
{}

// Compiling ex_exception.cpp

g++ -ftemplate-depth-128 -Wno-unused-local-typedefs 
-ftrack-macro-expansion=0 -O0 -fno-inline -Wall -g -march=i686 -m32 
-fvisibility-inlines-hidden -fvisibility=hidden -c -o "ex_exception.o" 
"ex_exception.cpp"

// ex_xml_exception.hpp

#ifndef EX_XML_EXCEPTION_HPP
#define EX_XML_EXCEPTION_HPP

#include <exception>
#include "ex_decl.hpp"
#include "ex_exception.hpp"

class EX_VISIBLE ex_xml_exception :
     public virtual ex_exception
{
public:
     typedef enum {
         xml_archive_parsing_error,
         xml_archive_tag_mismatch,
         xml_archive_tag_name_error
     } ex_exception_code;
     EX_DECL ex_xml_exception(
         ex_exception_code c,
         const char * e1 = 0,
         const char * e2 = 0
     );
     EX_DECL ex_xml_exception(ex_xml_exception const &) ;
     EX_DECL const char * what() const throw() ;
};

#endif // EX_XML_EXCEPTION_HPP

// ex_xml_exception.cpp

#include <exception>

#define BLD_EX_EXAMPLE
#include "ex_xml_exception.hpp"

EX_DECL ex_xml_exception::ex_xml_exception(ex_exception_code c,const 
char * e1,const char * e2) :
         ex_exception(other_exception, e1, e2)
     {
         switch(c){
         case xml_archive_parsing_error:
             ex_exception::append(0, "unrecognized XML syntax");
             break;
         case xml_archive_tag_mismatch:
             ex_exception::append(0, "XML start/end tag mismatch");
             if(0 != e1){
                 ex_exception::append(0, " - ");
                 ex_exception::append(0, e1);
             }
             break;
         case xml_archive_tag_name_error:
             ex_exception::append(0, "Invalid XML tag name");
             break;
         default:
             ex_exception::append(0, "programming error");
             break;
         }
     }

EX_DECL ex_xml_exception::ex_xml_exception(ex_xml_exception const & oth) :
        std::exception(oth),
        ex_exception(oth)
        {
        }
        
EX_DECL const char * ex_xml_exception::what() const throw()
        {
        return ex_exception::what();
        }

// Compiling Compiling ex_xml_exception.cpp

g++ -ftemplate-depth-128 -Wno-unused-local-typedefs 
-ftrack-macro-expansion=0 -O0 -fno-inline -Wall -g -march=i686 -m32 
-fvisibility-inlines-hidden -fvisibility=hidden -c -o 
"ex_xml_exception.o" "ex_xml_exception.cpp"

// Linking to ibexmp

g++ "-Wl,--out-implib,libexmp.dll.a" -o "libexmp.dll" -shared 
-Wl,--start-group "ex_exception.o" "ex_xml_exception.o" -Wl,-Bstatic 
-Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32

// throw_exception_ex.cpp

#include "ex_xml_exception.hpp"
template<class E> void throw_exception(E const & e) { throw e; }
int main(int argc,char * argv[])
     {
        if (argc > 1)
        {
 
throw_exception(ex_xml_exception(ex_xml_exception::xml_archive_parsing_error));
         }
        return 0;
     }

// Compiling throw_exception_ex.cpp

g++ -ftemplate-depth-128 -Wno-unused-local-typedefs 
-ftrack-macro-expansion=0 -O0 -fno-inline -Wall -g -march=i686 -m32 
-fvisibility-inlines-hidden -fvisibility=hidden -c -o 
"throw_exception_ex.o" "throw_exception_ex.cpp"

// Linking libthr_exmp

g++ "-Wl,--out-implib,libthr_exmp.dll.a" -o "libthr_exmp.dll" -shared 
-Wl,--start-group "throw_exception_ex.o" "libexmp.dll.a" -Wl,-Bstatic 
-Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32

// Result of this last link:

throw_exception_ex.o: In function `ZN16ex_xml_exceptionD1Ev':
ex_xml_exception.hpp:8: undefined reference to `vtable for ex_xml_exception'
ex_xml_exception.hpp:8: undefined reference to `vtable for ex_xml_exception'
ex_xml_exception.hpp:8: undefined reference to `vtable for ex_xml_exception'
ex_xml_exception.hpp:8: undefined reference to `VTT for ex_xml_exception'
collect2.exe: error: ld returned 1 exit status

If I remove the declaration and definition of ex_xml_exception::what(), 
since it is not needed, when linking I get:

throw_exception_ex.o:throw_exception_ex.cpp:(.rdata$_ZTV16ex_xml_exception[__ZTV16ex_xml_exception]+0x20):
 
undefined reference to `virtual thunk to ex_exception::what() const'
throw_exception_ex.o:throw_exception_ex.cpp:(.rdata$_ZTC16ex_xml_exception4_12ex_exception[__ZTC16ex_xml_exception4_12ex_exception]+0x38):
 
undefined reference to `virtual thunk to ex_exception::what() const'
collect2.exe: error: ld returned 1 exit status

which was the error in my OP.

Any help deciphering ehat is wrong with either mingw-64/gcc-5.1 or what 
is wrong wit the code that causes the link error would be greatly 
appreciated. The same problem occurs with mingw-64/gcc-4.9.2 and 
mingw-64/gcc-4.8.5. I can compile successfully with all versions of VC++ 
but have similar problems compiling with clang targeting mingw-64/gcc on 
Windows from release 3.4 on up.


















------------------------------------------------------------------------------
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to