Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

linking error when building Google test on mac (commandline)

I am currently trying to build some test code that uses Google C++ Test framework but I keep getting an error stating

ld: warning: in /usr/local/lib/libgtest.dylib, file was built for unsupported file format which is not the architecture being linked (i386)

I have tried to make the issue as simple as possible:

I have a main function cmtest.cc

#include <gtest/gtest.h>

/** Main entry point */
int main(int argc, char**argv, char**envArg)
{
    testing::InitGoogleTest(&argc, argv);
    return(RUN_ALL_TESTS());
}

really basic test code CrazyTest.cc

#include <gtest/gtest.h>
TEST(CrazyTest, one) {
    EXPECT_EQ(2, 2);
}

I use the following commands to build gtest and my test code.

g++ -o CrazyTest.o -c -Wall -Werror=non-virtual-dtor -pipe -std=c++98 -fno-rtti -fno-exceptions -fno-strict-aliasing -Wno-deprecated -g -arch i386 -arch x86_64 -mmacosx-version-min=10.5.4 -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_HAS_RTTI=0 -I/opt/gtest-1.6.0/include CrazyTest.cc

g++ -o cmtest.o -c -Wall -Werror=non-virtual-dtor -pipe -std=c++98 -fno-rtti -fno-exceptions -fno-strict-aliasing -Wno-deprecated -g -arch i386 -arch x86_64 -mmacosx-version-min=10.5.4 -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_HAS_RTTI=0 -I/opt/gtest-1.6.0/include cmtest.cc

g++ -o gtest-all.o -c -Wall -Werror=non-virtual-dtor -pipe -std=c++98 -fno-rtti -fno-exceptions -fno-strict-aliasing -Wno-deprecated -g -arch i386 -arch x86_64 -mmacosx-version-min=10.5.4 -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_HAS_RTTI=0 -I/opt/gtest-1.6.0 -I/opt/gtest-1.6.0/include /opt/gtest-1.6.0/src/gtest-all.cc

ar rc libgtest.a gtest-all.o

ranlib libgtest.a

g++ -o cmtest -arch i386 -arch x86_64 -mmacosx-version-min=10.5.4 CrazyTest.o cmtest.o -lstdc++ -lgtest

The final build step gives me the following error and I am unable to figure out why. I am able to get the actual tests (not the simple one shown) to build on other OSs the mac OS (leopard) is giving me problems.

 ld: warning: in /usr/local/lib/libgtest.dylib, file was built for unsupported file format which is not the architecture being linked (i386)
Undefined symbols for architecture i386:
  "testing::Test::~Test()", referenced from:
      CrazyTest_one_Test::~CrazyTest_one_Test()in CrazyTest.o
      CrazyTest_one_Test::~CrazyTest_one_Test()in CrazyTest.o
  "testing::internal::AssertHelper::~AssertHelper()", referenced from:
      CrazyTest_one_Test::TestBody()      in CrazyTest.o
  "testing::Test::Test()", referenced from:
      CrazyTest_one_Test::CrazyTest_one_Test()in CrazyTest.o
  "testing::internal::GetTestTypeId()", referenced from:
      __static_initialization_and_destruction_0(int, int)in CrazyTest.o
  "testing::Test::TearDown()", referenced from:
      vtable for CrazyTest_one_Testin CrazyTest.o
  "testing::internal::EqFailure(char const*, char const*, testing::internal::String const&, testing::internal::String const&, bool)", referenced from:
      testing::AssertionResult testing::internal::CmpHelperEQ<int, int>(char const*, char const*, int const&, int const&)in CrazyTest.o
  "testing::UnitTest::GetInstance()", referenced from:
      _main in cmtest.o
  "testing::internal::IsTrue(bool)", referenced from:
      testing::internal::scoped_ptr<std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> > >::reset(std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >*)in CrazyTest.o
      testing::internal::scoped_ptr<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >::reset(std::basic_string<char, std::char_traits<char>, std::allocator<char> >*)in CrazyTest.o
  "testing::UnitTest::Run()", referenced from:
      _main in cmtest.o
  "testing::internal::AssertHelper::operator=(testing::Message const&) const", referenced from:
      CrazyTest_one_Test::TestBody()      in CrazyTest.o
  "testing::internal::AssertHelper::AssertHelper(testing::TestPartResult::Type, char const*, int, char const*)", referenced from:
      CrazyTest_one_Test::TestBody()      in CrazyTest.o
  "testing::AssertionSuccess()", referenced from:
      testing::AssertionResult testing::internal::CmpHelperEQ<int, int>(char const*, char const*, int const&, int const&)in CrazyTest.o
  "testing::Test::SetUp()", referenced from:
      vtable for CrazyTest_one_Testin CrazyTest.o
  "testing::internal::MakeAndRegisterTestInfo(char const*, char const*, char const*, char const*, void const*, void (*)(), void (*)(), testing::internal::TestFactoryBase*)", referenced from:
      __static_initialization_and_destruction_0(int, int)in CrazyTest.o
  "testing::InitGoogleTest(int*, char**)", referenced from:
      _main in cmtest.o
ld: symbol(s) not found for architecture i386
collect2: ld returned 1 exit status
lipo: can't open input file: /var/tmp//ccZQiF8k.out (No such file or directory)

I have defined -arch i386 and -arch x86_64 for everything I have built so I am unable to figure out what I have missed. I don't do a lot of programming on Macs and this particular issue has me stuck.

Any suggestions would be helpful.

like image 925
gnash117 Avatar asked Feb 07 '12 20:02

gnash117


2 Answers

Solution found. It turns out that the build instructions used are correct the issue was that on the computer that the build was being performed another developer had done some work with Google Test Framework 1.5 and they had installed the libraries on the computer in the compilers search path. This resulted in the compiler finding the other library first that was not compiled using multiple architecture options.

like image 72
gnash117 Avatar answered Oct 03 '22 22:10

gnash117


Compile gtest and your project with the same compiler (-flags).

If you compiled gtest with Apple g++ and meanwhile installed gcc with e.g. homebrew, linking to gtest will cause this error. This is exactly the reason why Google advices to integrate gtest statically linked in your project, and not to use precompiled binaries.

like image 42
ManuelSchneid3r Avatar answered Oct 04 '22 00:10

ManuelSchneid3r