googletest Undefined symbols for architecture x86_64 error
Asked Answered
C

2

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.

Cockscomb answered 6/8, 2016 at 9:10 Comment(9)
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.Gantlet
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.Kirkendall
No wait, where are you linking your program? Where's the command?Gantlet
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 -lgtestKirkendall
"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.Gantlet
On top of adding -D_GLIBCXX_USE_CXX11_ABI=1 for gtest and my project ?Kirkendall
It looks like cxx11 abi is the default for gcc 6.0 so this is probably redundant.Gantlet
The compiler does not recognize the -stdlib=libstdc++ option ;-)Kirkendall
Sorry my mistake. This is a clang switch.Gantlet
Z
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.

Zoellick answered 18/12, 2019 at 2:22 Comment(0)
S
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

Sherrylsherurd answered 28/2, 2021 at 15:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.