3

Let GTEST_DIR be the environment variable storing the path to the googletest directory. (I cloned googletest-master from googletest's github repo.)

I cd'ed into $GTEST_DIR, did a mkdir build && cd build, then executed the following command :

cmake .. -DCMAKE_C_COMPILER=$GNU-6.0.0/bin/gcc-6.0.0 -DCMAKE_CXX_COMPILER=$GNU-6.0.0/bin/g++-6.0.0

where GNU-6.0.0 is the path to my gnu install. This generated a Makefile inside $GTEST_DIR/build that I tweaked as follows : I've added

CC = $GNU-6.0.0/bin/gcc-6.0.0
CXX = $GNU-6.0.0/bin/g++-6.0.0

at its beginning, to be sure that the c and c++ compilers that will be used will be those I want to be used. Then I ran make which produced archive files libgtest.a and libgtest_main.a inside $GTEST_DIR/build.

Next step : in a same folder I put a main test source file main.cpp containg :

#include "path/to/gtest.h"

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

and a dummy test dummy_test.cpp containing :

#include "path/to/gtest.h"

TEST(dummy_test, test1)
{
    EXPECT_EQ(1,1);
}

and a Makefile containing :

CC = gcc-6.0.0
CXX = g++-6.0.0

CPPFLAGS += -isystem $(GTEST_DIR)/include
LDFLAGS := -L/usr/lib -lpthread -L$(GTEST_DIR)/build -lgtest

all :
    $(CXX) -o cpptests $(CPPFLAGS) ./main.cpp ./dummy_test.cpp $(LDFLAGS)

clean :
    rm -rf ./cpptests

Running make I have this output :

Undefined symbols for architecture x86_64:
  "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::end() const", referenced from:
      testing::internal::XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in libgtest.a(gtest-all.cc.o)
  "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::data() const", referenced from:
      testing::internal::PrintStringTo(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::basic_ostream<char, std::char_traits<char> >*) in libgtest.a(gtest-all.cc.o)
      __gnu_cxx::__enable_if<std::__is_char<char>::__value, bool>::__type std::operator==<char>(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&) in libgtest.a(gtest-all.cc.o)
  "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::find(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned long) const", referenced from:
      bool testing::(anonymous namespace)::IsSubstringPred<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(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&) in libgtest.a(gtest-all.cc.o)
  "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::find(char, unsigned long) const", referenced from:
      testing::internal::SplitString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*) in libgtest.a(gtest-all.cc.o)
      testing::internal::FormatDeathTestOutput(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in libgtest.a(gtest-all.cc.o)
  "std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::size() const", referenced from:
      testing::internal::(anonymous namespace)::SplitEscapedString(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) in libgtest.a(gtest-all.cc.o)

...

      ...
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status
make: *** [all] Error 1

The entire output is in this snippet while the output of nm libgtest.a is in this snippet.

Precision : I am under mac os x 10.10.5. As I want to continue working, developping code and testing it, while the aforementionned error with gcc/g++ 6.0.0 is solved, I tried to switch to another compiler : clang, and I remarked that I had no error at all with it.

Remark libgtest.a was initially (that is, before I asked this question) built "by error" with clang and used in tests with g++-6.1.0 when I encountered the error, that's why I decided to rebuild libgtest.a with g++-6.1.0, thinking that it would solve the problem, but it didn't, which led me to post here.

Olórin
  • 3,367
  • 2
  • 22
  • 42
  • You have some parts of your program (including the 3rd party libs) built with -std=c++11 and some without. Bring them all in line. See e.g.[this](http://stackoverflow.com/questions/33394934/converting-std-cxx11string-to-stdstring). – n. m. could be an AI Aug 06 '16 at 09:17
  • Ok, I `cmake`'d with `-DCMAKE_C_COMPILER=$GNU-6.0.0/bin/gcc-6.0.0 -DCMAKE_CXX_COMPILER=$GNU-6.0.0/bin/g++-6.0.0 -D_GLIBCXX_USE_CXX11_ABI=1` instead, put `$(CXX) = g++-6.0.0 -DCMAKE_CXX_FLAGS=-D_GLIBCXX_USE_CXX11_ABI=1` in the `Makefile` generated by `cmake`, did the same for my dummy `Makefile` and ended up having the very same error. – Olórin Aug 06 '16 at 10:17
  • No wait, where are you *linking* your program? Where's the command? – n. m. could be an AI Aug 06 '16 at 10:23
  • I was wrong using the term **linking**, the only command is `$(CXX) $(CPPFLAGS) -I$(GTEST_DIR)/include $(LDFLAGS) -lgtest -lpthread ./main.cpp ./dummy_test.cpp -o cpptests` with `LDFLAGS := -lpthread -L/usr/lib -L$(GTEST_DIR)/build -lgtest` – Olórin Aug 06 '16 at 10:45
  • "As I am under mac os x, if instead gnu's gcc/g++ 6.0.0 I use clang's, I do not have this error and everything work's perfectly." Try adding `-stdlib=libstdc++` to your CXX and LD flags. – n. m. could be an AI Aug 06 '16 at 14:04
  • On top of adding `-D_GLIBCXX_USE_CXX11_ABI=1` for `gtest` and my project ? – Olórin Aug 06 '16 at 14:06
  • It looks like cxx11 abi is the default for gcc 6.0 so this is probably redundant. – n. m. could be an AI Aug 06 '16 at 15:23
  • The compiler does not recognize the `-stdlib=libstdc++` option ;-) – Olórin Aug 06 '16 at 15:47
  • Sorry my mistake. This is a clang switch. – n. m. could be an AI Aug 06 '16 at 15:59

2 Answers2

4

The problem seems to be due to some linking issues. Have you used the linker flags correctly. For gtest, we need to compile with -lgtest and the linker can link it correctly. Similarly, we need to have the flags for all possible libraries that we are linking against.

The code

TEST(dummy_test, test1) { EXPECT_EQ(1,1); }

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

compiles perfectly for me with command

clang++ -std=c++11 main.cpp -lgtest

and I could run the single test without an issue.

esrujan
  • 41
  • 5
0

I was getting following error

Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

with the command

/usr/bin/g++ -g testgoogletestsetup.cpp -std=c++11 -o testgoogletestsetup -lgtest

Solution:
Library gtest_main needs to be linked (and the library gtest too) to compile it successfully. For that provide the linker flags as -lgtest_main as shown in below command.

/usr/bin/g++ -g testgoogletestsetup.cpp -std=c++11 -o testgoogletestsetup -lgtest -lgtest_main