I am building a small static library that currently contains just a single object file. When I try to link it to a program I get a range of 'undefined reference' errors. All of the errors appear to be related to definitions in the .cpp file.
The library header file (except.hpp) is:
#ifndef FOD_REEF_EXCEPT
#define FOD_REEF_EXCEPT
#include <exception>
#include <string>
namespace REEF
{
class REEFException : public std::exception
{
public:
REEFException() = default;
REEFException(const char* file, int line);
virtual ~REEFException() = default;
virtual const char* what() const noexcept;
virtual const std::string What() const noexcept { return std::string(what()); }
virtual const std::string Where() const noexcept;
private:
std::string _where;
};
}
#endif // FOD_REEF_EXCEPT
The implementation file (except.cpp) is:
#include "except.hpp"
const char* defaultExceptionMessage = "Undefined exception";
REEF::REEFException::REEFException(const char* file, int line)
{
_where = "line " + std::to_string(line) + " in " + file;
}
const char* REEF::REEFException::what() const noexcept
{
return defaultExceptionMessage;
}
const std::string REEF::REEFException::Where() const noexcept
{
return _where;
}
I compile the object file (except.o) with:
g++ -c -std=c++17 -Wall -Wextra -I~/dev/project/fod -o obj/except.o src/except.cpp
and then create a library with:
ar rvs bin/libreef.a obj/except.o
This successfully creates ~/dev/project/fod/reef/bin/libreef.a. Running ar -t libreef.a shows
except.o
When I compile a test program, from a different directory, with
g++ -std=c++17 -Wall -Wextra -I~/dev/project/fod -L~/dev/project/fod/reef/bin -lreef src/test.cpp -o bin/test
I get a range of undefined reference errors:
test.cpp:46: undefined reference to `REEF::REEFException::REEFException(char const*, int)'
test.cpp:46: undefined reference to `typeinfo for REEF::REEFException'
/tmp/ccrlvFmY.o: In function `TestAsserts()':
test.cpp:133: undefined reference to `REEF::REEFException::REEFException(char const*, int)'
test.cpp:133: undefined reference to `typeinfo for REEF::REEFException'
test.cpp:135: undefined reference to `REEF::REEFException::REEFException(char const*, int)'
test.cpp:135: undefined reference to `typeinfo for REEF::REEFException'
/tmp/ccrlvFmY.o: In function `REEF::REEFException::REEFException()':
except.hpp:46: undefined reference to `vtable for REEF::REEFException'
/tmp/ccrlvFmY.o: In function `REEF::REEFException::~REEFException()':
except.hpp:59: undefined reference to `vtable for REEF::REEFException'
/tmp/ccrlvFmY.o:(.gcc_except_table+0x6c): undefined reference to `typeinfo for REEF::REEFException'
/tmp/ccrlvFmY.o:(.gcc_except_table+0xb0): undefined reference to `typeinfo for REEF::REEFException'
However, if I don't compile against the library but instead compile directly against except.o, like this
g++ -std=c++17 -Wall -Wextra -I~/dev/project/fod src/test.cpp ../obj/except.o -o bin/test
from the test directory then it compiles and runs just fine.
I can't work out why linking with the library is a problem, it's just a container for the object file isn't it? I know the linker is finding the correct library file because if I change it's name I get an error stating that it can't be found.
Can anyone help me? I have no more hair to lose.