Reputation: 97
I did a dist-upgrade yesterday and now I'm getting undefined reference errors when I compile tests using GMock and clang++; it is working fine with g++ though. GTest and GMock are compiled from source and installed with Cmake.
I was wondering if anyone knows why it isn't linking properly?
I'm compiling with:
clang++-3.7 -Wall -Wextra -pedantic -std=c++11 -Wshadow a.cpp -o a.out -lgtest -lgmock -pthread
I'm gettting these errors:
/tmp/a-bb74fa.o: In function `testing::internal::FunctionMockerBase<int ()>::DescribeDefaultActionTo(std::tuple<> const&, std::ostream*) const':
a.cpp:(.text._ZNK7testing8internal18FunctionMockerBaseIFivEE23DescribeDefaultActionToERKSt5tupleIJEEPSo[_ZNK7testing8internal18FunctionMockerBaseIFivEE23DescribeDefaultActionToERKSt5tupleIJEEPSo]+0x8e): undefined reference to `testing::internal::FormatFileLocation(char const*, int)'
/tmp/a-bb74fa.o: In function `testing::internal::ExpectationBase::DescribeLocationTo(std::ostream*) const':
a.cpp:(.text._ZNK7testing8internal15ExpectationBase18DescribeLocationToEPSo[_ZNK7testing8internal15ExpectationBase18DescribeLocationToEPSo]+0x43): undefined reference to `testing::internal::FormatFileLocation(char const*, int)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [a.out] Error 1
The source code:
#include<gtest/gtest.h>
#include<gmock/gmock.h>
#include <iostream>
class printable{
public:
virtual int print() = 0;
};
class A{
public:
A( printable* b ) :
obj( b )
{}
int doit(){return obj->print();}
private:
printable* obj;
};
class MockPrintable : public printable{
public:
MOCK_METHOD0( print, int() );
};
TEST( test, returnStuff ){
MockPrintable b;
A a( &b );
EXPECT_CALL( b, print() )
.WillOnce( testing::Return( 1 ) )
.WillOnce( testing::Return( 2 ) )
.WillOnce( testing::Return( 3 ) );
EXPECT_EQ( 1,a.doit() );
EXPECT_EQ( 2,a.doit() );
EXPECT_EQ( 3,a.doit() );
}
int main( int argc, char* argv[] ){
::testing::InitGoogleMock( &argc, argv );
return RUN_ALL_TESTS();
}
I've narrowed the problem down somewhat to libgcc-5-dev
and libstdc++-5-dev
packages.
libstdc++-5-dev
causes this error:
/usr/local/include/gtest/gtest.h:54:10: fatal error: 'limits' file not found
#include <limits>
libstdc++-5-dev
causes a lot of undefined reference errors relating to
gmock.
I can't seem to link against older versions using -l
and -L
. Searching
around turns up results advising against trying to statically link against these
and to use older versions of the compiler instead. But, the compiler
dependencies now requires the same *-5-dev
packages according to apt-get.
You can prevent apt-get from using these package by inserting this into
/etc/apt/preferences:
Package: libgcc-5-dev
Pin: release *
Pin-Priority: -1
Package: libstdc++-5-dev
Pin: release *
Pin-Priority: -1
and just dist-upgrade
from there, but it prevents g++, clang and other things
from updating so it isn't worth it; apt-get
suggests removing clang
as part
of dist-upgrade
anyhow.
Lastly, I tried to use the precompiled-binary for clang-3.8 from their website but it gave me a
humongous wall of undefined reference to std::< everything >. I did get a
hello world program to compile though so it can at least find std::cout
and
std::endl
.
Upvotes: 1
Views: 1907
Reputation: 875
I think you are victim of the ABI change introduced with libstdc++ in v5. They had to change the implementation of std::string
, because C++11 mandates a particular implementation while was not the case before. That lead to changes in symbol names. The problem is specific to migrating from pre-v5 libstdc++ (gcc) to v5 or higher and should therefore not happen again.
Upvotes: 1