Googletest:CLANG 在 GCC 失败的地方编译

Googletest: CLANG compiles where GCC fails

这是一个使用 gtest 的非常简单的脚本(保存在文件 gt.cpp 中)

#include<gtest/gtest.h>

double timesTwo(double x){return x*2;}

TEST(testTimesTwo, integerTests){EXPECT_EQ(6, timesTwo(3));}

int main(int argc, char* argv[]){
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

使用 CLANG 可以很好地编译脚本 (Apple clang version 11.0.3)

clang++ -std=c++17 -lgtest gt.cpp -o gt

但 GCC 失败 (g++ (GCC) 10.2.0)

g++ -std=c++17 -lgtest gt.cpp -o gt

gt.cpp:2:9: fatal error: gtest/gtest.h: No such file or directory
    2 | #include<gtest/gtest.h>
      |   

使用 CLANG 中的 -H 选项,我看到头文件包含在 /usr/local/include 中。另外,我可以在 /usr/local/bin/ 中找到 libgtest.a 文件。所以,我做到了

g++ -std=c++17 gt.cpp -o gt -I/usr/local/include/ -L/usr/local/lib/ -lgtest 

得到一长串以

开头的未定义符号
Macavity:test remi$ g++ -std=c++17  gt.cpp -o gt -I/usr/local/include/ -L/usr/local/lib/ -lgtest
Undefined symbols for architecture x86_64:
  "__ZN7testing8internal9EqFailureEPKcS2_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_b", referenced from:
      __ZN7testing8internal18CmpHelperEQFailureIidEENS_15AssertionResultEPKcS4_RKT_RKT0_ in ccrUwUPO.o
  "__ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4findEcm", referenced from:
      __ZN7testing8internal11SplitStringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEcPNS1_6vectorIS7_NS5_IS7_EEEE in libgtest.a(gtest-all.cc.o)
      __ZN7testing8internalL21FormatDeathTestOutputERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE in libgtest.a(gtest-all.cc.o)
  "__ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7compareEmmPKcm", referenced from:

你能帮我弄清楚为什么GCC在这里编译失败吗?

这是通过 http://demangler.com/

传递的错误消息
Undefined symbols for architecture x86_64:
  "_testing::internal::EqFailure(char const*, char const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool)", referenced from:
      _testing::AssertionResult testing::internal::CmpHelperEQFailure<int, double>(char const*, char const*, int const&, double const&) in ccrUwUPO.o
  "_std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::find(char, unsigned long) const", referenced from:
      _testing::internal::SplitString(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char, std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >*) in libgtest.a(gtest-all.cc.o)
      _testing::internal::FormatDeathTestOutput(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) in libgtest.a(gtest-all.cc.o)
  "_std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::compare(unsigned long, unsigned long, char const*, unsigned long) const", referenced from:

请注意,第二个和第三个错误抱怨链接器无法找到以下实现:std::string::find(char, unsigned long)std::string::compare(unsigned long, unsigned long, char const*, unsigned long) const

这些是标准 C++ 库的一部分。由于 std::string 是模板,它的某些部分是使用该模板的库的一部分,但在某些情况下它可以是 C++ 运行时的一部分。

现在我怀疑您使用 clang 编译了 gtest 并尝试在使用 gcc 构建测试时使用它(反之亦然)。 std::string 在两个编译器上的一些不同实现导致可用符号的差异。

所以请确保 gtest 和测试应用程序是使用相同的编译器构建的。

这里是binary compatibility between gcc and clang的一些描述。有一些提示是什么问题,但不是很正式(也许我会找到更好的文档)。