gtest - 链接器找到“libgtest.a”但仍然抱怨对“testing::Test::Test()”的未定义引用

gtest - linker finds `libgtest.a` but still complains undefined reference to `testing::Test::Test()`

我是 google C++ 测试的新手。 我通过 downloading source code from GitHub 安装了 google 测试。 我用 CMake 构建它并将其安装到 $HOME/.local。 然后我用下面的代码测试。

#include "gtest/gtest.h"

TEST(Foo, Bar) {
  EXPECT_TRUE(true);
}

我用

编译了它

clang++ -std=c++1z -I$HOME/.local/include -L$HOME/.local/lib -lgtest -lgtest_main a.cc

它给出了以下 linker 错误

/tmp/a-dc64ec.o: In function `Foo_Bar_Test::TestBody()':
a.cc:(.text+0x5f): undefined reference to `testing::Message::Message()'
a.cc:(.text+0x81): undefined reference to `testing::internal::GetBoolAssertionFailureMessage[abi:cxx11](testing::AssertionResult const&, char const*, char const*, char const*)'
a.cc:(.text+0xaa): undefined reference to `testing::internal::AssertHelper::AssertHelper(testing::TestPartResult::Type, char const*, int, char const*)'
a.cc:(.text+0xbc): undefined reference to `testing::internal::AssertHelper::operator=(testing::Message const&) const'
a.cc:(.text+0xca): undefined reference to `testing::internal::AssertHelper::~AssertHelper()'
a.cc:(.text+0x109): undefined reference to `testing::internal::AssertHelper::~AssertHelper()'
/tmp/a-dc64ec.o: In function `__cxx_global_var_init.1':
a.cc:(.text.startup+0x8a): undefined reference to `testing::internal::GetTestTypeId()'
a.cc:(.text.startup+0x134): undefined reference to `testing::internal::MakeAndRegisterTestInfo(char const*, char const*, char const*, char const*, testing::internal::CodeLocation, void const*, void (*)(), void (*)(), testing::internal::TestFactoryBase*)'
/tmp/a-dc64ec.o: In function `testing::internal::SuiteApiResolver<testing::Test>::GetSetUpCaseOrSuite(char const*, int)':
a.cc:(.text._ZN7testing8internal16SuiteApiResolverINS_4TestEE19GetSetUpCaseOrSuiteEPKci[_ZN7testing8internal16SuiteApiResolverINS_4TestEE19GetSetUpCaseOrSuiteEPKci]+0x6a): undefined reference to `testing::internal::IsTrue(bool)'
a.cc:(.text._ZN7testing8internal16SuiteApiResolverINS_4TestEE19GetSetUpCaseOrSuiteEPKci[_ZN7testing8internal16SuiteApiResolverINS_4TestEE19GetSetUpCaseOrSuiteEPKci]+0x9b): undefined reference to `testing::internal::GTestLog::GTestLog(testing::internal::GTestLogSeverity, char const*, int)'
a.cc:(.text._ZN7testing8internal16SuiteApiResolverINS_4TestEE19GetSetUpCaseOrSuiteEPKci[_ZN7testing8internal16SuiteApiResolverINS_4TestEE19GetSetUpCaseOrSuiteEPKci]+0x122): undefined reference to `testing::internal::GTestLog::~GTestLog()'
a.cc:(.text._ZN7testing8internal16SuiteApiResolverINS_4TestEE19GetSetUpCaseOrSuiteEPKci[_ZN7testing8internal16SuiteApiResolverINS_4TestEE19GetSetUpCaseOrSuiteEPKci]+0x137): undefined reference to `testing::internal::GTestLog::~GTestLog()'
/tmp/a-dc64ec.o: In function `testing::internal::SuiteApiResolver<testing::Test>::GetTearDownCaseOrSuite(char const*, int)':
a.cc:(.text._ZN7testing8internal16SuiteApiResolverINS_4TestEE22GetTearDownCaseOrSuiteEPKci[_ZN7testing8internal16SuiteApiResolverINS_4TestEE22GetTearDownCaseOrSuiteEPKci]+0x6a): undefined reference to `testing::internal::IsTrue(bool)'
a.cc:(.text._ZN7testing8internal16SuiteApiResolverINS_4TestEE22GetTearDownCaseOrSuiteEPKci[_ZN7testing8internal16SuiteApiResolverINS_4TestEE22GetTearDownCaseOrSuiteEPKci]+0x9b): undefined reference to `testing::internal::GTestLog::GTestLog(testing::internal::GTestLogSeverity, char const*, int)'
a.cc:(.text._ZN7testing8internal16SuiteApiResolverINS_4TestEE22GetTearDownCaseOrSuiteEPKci[_ZN7testing8internal16SuiteApiResolverINS_4TestEE22GetTearDownCaseOrSuiteEPKci]+0x118): undefined reference to `testing::internal::GTestLog::~GTestLog()'
a.cc:(.text._ZN7testing8internal16SuiteApiResolverINS_4TestEE22GetTearDownCaseOrSuiteEPKci[_ZN7testing8internal16SuiteApiResolverINS_4TestEE22GetTearDownCaseOrSuiteEPKci]+0x12d): undefined reference to `testing::internal::GTestLog::~GTestLog()'
/tmp/a-dc64ec.o: In function `Foo_Bar_Test::~Foo_Bar_Test()':
a.cc:(.text._ZN12Foo_Bar_TestD2Ev[_ZN12Foo_Bar_TestD2Ev]+0x14): undefined reference to `testing::Test::~Test()'
/tmp/a-dc64ec.o: In function `Foo_Bar_Test::Foo_Bar_Test()':
a.cc:(.text._ZN12Foo_Bar_TestC2Ev[_ZN12Foo_Bar_TestC2Ev]+0x1b): undefined reference to `testing::Test::Test()'
/tmp/a-dc64ec.o:(.rodata+0x20): undefined reference to `testing::Test::SetUp()'
/tmp/a-dc64ec.o:(.rodata+0x28): undefined reference to `testing::Test::TearDown()'
/tmp/a-dc64ec.o:(.rodata+0x60): undefined reference to `typeinfo for testing::Test'
/home/wyq/.local/lib/libgtest_main.a(gtest_main.cc.o): In function `main':
gtest_main.cc:(.text+0x32): undefined reference to `testing::InitGoogleTest(int*, char**)'
/home/wyq/.local/lib/libgtest_main.a(gtest_main.cc.o): In function `RUN_ALL_TESTS()':
gtest_main.cc:(.text._Z13RUN_ALL_TESTSv[_Z13RUN_ALL_TESTSv]+0x5): undefined reference to `testing::UnitTest::GetInstance()'
gtest_main.cc:(.text._Z13RUN_ALL_TESTSv[_Z13RUN_ALL_TESTSv]+0xd): undefined reference to `testing::UnitTest::Run()'
clang-12: error: linker command failed with exit code 1 (use -v to see invocation)

--verbose 添加到 clang 会得到以下 linker 命令

"/usr/bin/ld" -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/5.4.0/crtbegin.o -L/home/wyq/.local/lib -L/usr/lib/gcc/x86_64-linux-gnu/5.4.0 -L/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../.. -L/home/wyq/.local/bin/../lib -L/lib -L/usr/lib -lgtest -lgtest_main a.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/5.4.0/crtend.o /usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crtn.o

--verbose添加到ld表明它实际上找到了libgtest.alibgtest_main.a

"/usr/bin/ld" -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/5.4.0/crtbegin.o -L/home/wyq/.local/lib -L/usr/lib/gcc/x86_64-linux-gnu/5.4.0 -L/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../.. -L/home/wyq/.local/bin/../lib -L/lib -L/usr/lib -lgtest -lgtest_main a.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/5.4.0/crtend.o /usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crtn.o --verbose 2>&1 | grep gtest
attempt to open /home/wyq/.local/lib/libgtest.so failed
attempt to open /home/wyq/.local/lib/libgtest.a succeeded
attempt to open /home/wyq/.local/lib/libgtest_main.so failed
attempt to open /home/wyq/.local/lib/libgtest_main.a succeeded
(/home/wyq/.local/lib/libgtest_main.a)gtest_main.cc.o
/home/wyq/.local/lib/libgtest_main.a(gtest_main.cc.o): In function `main':
gtest_main.cc:(.text+0x32): undefined reference to `testing::InitGoogleTest(int*, char**)'
/home/wyq/.local/lib/libgtest_main.a(gtest_main.cc.o): In function `RUN_ALL_TESTS()':
gtest_main.cc:(.text._Z13RUN_ALL_TESTSv[_Z13RUN_ALL_TESTSv]+0x5): undefined reference to `testing::UnitTest::GetInstance()'
gtest_main.cc:(.text._Z13RUN_ALL_TESTSv[_Z13RUN_ALL_TESTSv]+0xd): undefined reference to `testing::UnitTest::Run()'

这是为什么?我怎样才能正确 link gtest 库?

链接器参数顺序错误

a.cc -lgtest -lgtest_main 

没有

-lgtest -lgtest_main a.cc