昨天我做了一个dist-upgrade,现在我在使用GMock和clang编译测试时遇到了未定义的引用错误;虽然它与g一起工作正常 . GTest和GMock从源代码编译并与Cmake一起安装 .
我想知道是否有人知道为什么它没有正确链接?
我正在编译:
clang++-3.7 -Wall -Wextra -pedantic -std=c++11 -Wshadow a.cpp -o a.out -lgtest -lgmock -pthread
我正在解决这些错误:
/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
源代码:
#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();
}
编辑:
我已经将问题缩小到 libgcc-5-dev
和 libstdc++-5-dev
包 .
libstdc++-5-dev
导致此错误:
/usr/local/include/gtest/gtest.h:54:10: fatal error: 'limits' file not
found
#include <limits>
libstdc++-5-dev
导致很多与gmock相关的 undefined reference 错误 .
我似乎无法使用 -l
和 -L
链接旧版本 . 搜索周围会显示结果,建议不要尝试静态链接这些并使用旧版本的编译器 . 但是,根据apt-get,编译器依赖项现在需要相同的 *-5-dev
包 .
您可以通过将此插入 /etc/apt/preferences:
来阻止apt-get使用这些包
Package: libgcc-5-dev
Pin: release *
Pin-Priority: -1
Package: libstdc++-5-dev
Pin: release *
Pin-Priority: -1
而且只是 dist-upgrade
从那里,但它阻止g,clang和其他东西更新,所以它是不值得的; apt-get
无论如何,建议删除 clang
作为 dist-upgrade
的一部分 .
最后,我尝试从他们的网站使用precompiled-binary for clang-3.8,但它给了我一个未定义的std :: <everything>引用的巨大墙 . 我确实得到了一个hello world程序来编译,所以它至少可以找到 std::cout
和 std::endl
.
1 回答
我认为你是v5中libstdc引入的ABI变化的受害者 . 他们不得不改变
std::string
的实施,因为C 11要求特定的实施,而事实并非如此 . 这导致符号名称的更改 . 该问题特定于从v5之前的libstdc(gcc)迁移到v5或更高版本,因此不应再次发生 .