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