0

Here is a very simple script using gtest (saved in file 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();
}

The script compiles fine with CLANG (Apple clang version 11.0.3)

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

but fails with 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>
      |   

Using the -H option in CLANG, I see the header file is included from /usr/local/include. Also, I can find the libgtest.a file in /usr/local/bin/. So, I did

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

and got a long list of undefined symbols starting with

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:

Can you help me figure out why GCC fails to compile here?

Remi.b
  • 17,389
  • 28
  • 87
  • 168
  • `-L/usr/local/include/` <-- Are you sure that's where the library file is (and not in e.g. `usr/local/lib`)? – Michael Oct 11 '21 at 12:19
  • The `which` command is for seeing the location of an executable, and is not necessarily related to the locations of library headers or library binaries. – aschepler Oct 11 '21 at 12:21
  • @Michael The first line outputted by `clang++ -H ...` is `. /usr/local/include/gtest/gtest.h`. Now that is for the header file. I am not sure about the library file. – Remi.b Oct 11 '21 at 12:27
  • That's the header/include file. I'm talking about the library (i.e. `libgtest.a` or whatever it's called). – Michael Oct 11 '21 at 12:27
  • @Michael Yes, you are right the library is probably included form `/usr/local/lib` (I confirm I can find `libgtest.a` over there). I also tried `g++ -std=c++17 gt.cpp -o gt -I/usr/local/include/ -L/usr/local/lib/ -lgtest` but it also return linker errors (undefined symbols). – Remi.b Oct 11 '21 at 12:30
  • I edited the post to simplify this discussion of where files are located, now that I understand it better thanks to your comments. – Remi.b Oct 11 '21 at 12:38
  • Problem is that library build by `gcc` is used by `clang`. There are some differences in case of C++ which makes this problematic see https://stackoverflow.com/a/11274684/1387438 – Marek R Oct 11 '21 at 14:25
  • @MarekR `clang` manages to compile while `gcc` does not. If I unedrstand what you are saying this is because `googletest` was compiled using `clang` on my machine. Is that right? If I reinstall `googletest`, comoiling with `gcc` (if I can figure out how to do that because I see no mention of the compiler in the makefile), then it should work with `GCC` (but maybe not with `clang`). – Remi.b Oct 11 '21 at 14:55
  • Problem persists in both directions. Do demanbgling of this messages and note liker complains it can't find symbols for `std::string` needed by `gtest`. Different implementations of `std::string` leads to different name mangling and this symbol can't be found. – Marek R Oct 11 '21 at 15:01

1 Answers1

2

Here is this error message passed through a 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:

Note that second and third error complains that linker can't find implementation of: std::string::find(char, unsigned long) and std::string::compare(unsigned long, unsigned long, char const*, unsigned long) const.

Those are parts of standard C++ library. Since std::string is template some parts of it are part of library which uses that template, but is some cases it can be part of C++ runtime.

Now I suspect that you compiled gtest with a clang and try use it when building test with gcc (or vice versa). A bit different implementations of std::string on both compilers lead to divergence in available symbols.

So please make sure that gtest and test application are build with same compiler.

Here is some description of binary compatibility between gcc and clang. There are some hints what problem is, but it is not very formal (maybe I will find better document).

Marek R
  • 32,568
  • 6
  • 55
  • 140