-1

I've got a project I'm writing in C++ in Xcode. I wanted to use Smart Pointers, so I changed the C++ Language Dialect to c++11 and the C++ Standard Library to libc++.

Now I get a huge number of linker errors when I try and run my project.

I'm using the AppGameKit 2 C++ library in my project, which is named libAGKMac.a. I can see that it's the source of the errors, but I'm not sure why.

A sample of the errors is here:

Undefined symbols for architecture i386:
"std::string::find(char, unsigned long) const", referenced from:
  zxing::oned::Code39Reader::decodeRow(int, zxing::Ref<zxing::BitArray>) in libAGKMac.a(Code39Reader.o)
"std::string::substr(unsigned long, unsigned long) const", referenced from:
  zxing::oned::MultiFormatUPCEANReader::decodeRow(int, zxing::Ref<zxing::BitArray>) in libAGKMac.a(MultiFormatUPCEANReader.o)
  zxing::oned::UPCAReader::maybeReturnResult(zxing::Ref<zxing::Result>) in libAGKMac.a(UPCAReader.o)
  zxing::oned::UPCEReader::convertUPCEtoUPCA(std::string) in libAGKMac.a(UPCEReader.o)
"std::string::compare(std::string const&) const", referenced from:
  std::map<std::string, zxing::common::CharacterSetECI*, std::less<std::string>, std::allocator<std::pair<std::string const, zxing::common::CharacterSetECI*> > >::operator[](std::string const&) in libAGKMac.a(CharacterSetECI.o)
  std::_Rb_tree<std::string, std::pair<std::string const, zxing::common::CharacterSetECI*>, std::_Select1st<std::pair<std::string const, zxing::common::CharacterSetECI*> >, std::less<std::string>, std::allocator<std::pair<std::string const, zxing::common::CharacterSetECI*> > >::_M_insert_unique(std::_Rb_tree_iterator<std::pair<std::string const, zxing::common::CharacterSetECI*> >, std::pair<std::string const, zxing::common::CharacterSetECI*> const&) in libAGKMac.a(CharacterSetECI.o)
  std::_Rb_tree<std::string, std::pair<std::string const, zxing::common::CharacterSetECI*>, std::_Select1st<std::pair<std::string const, zxing::common::CharacterSetECI*> >, std::less<std::string>, std::allocator<std::pair<std::string const, zxing::common::CharacterSetECI*> > >::_M_insert(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair<std::string const, zxing::common::CharacterSetECI*> const&) in libAGKMac.a(CharacterSetECI.o)
  std::_Rb_tree<std::string, std::pair<std::string const, zxing::common::CharacterSetECI*>, std::_Select1st<std::pair<std::string const, zxing::common::CharacterSetECI*> >, std::less<std::string>, std::allocator<std::pair<std::string const, zxing::common::CharacterSetECI*> > >::_M_insert_unique(std::pair<std::string const, zxing::common::CharacterSetECI*> const&) in libAGKMac.a(CharacterSetECI.o)
  std::_Rb_tree<std::string, std::pair<std::string const, zxing::common::CharacterSetECI*>, std::_Select1st<std::pair<std::string const, zxing::common::CharacterSetECI*> >, std::less<std::string>, std::allocator<std::pair<std::string const, zxing::common::CharacterSetECI*> > >::lower_bound(std::string const&) in libAGKMac.a(CharacterSetECI.o)
  zxing::multi::GenericMultipleBarcodeReader::doDecodeMultiple(zxing::Ref<zxing::BinaryBitmap>, zxing::DecodeHints, std::vector<zxing::Ref<zxing::Result>, std::allocator<zxing::Ref<zxing::Result> > >&, int, int) in libAGKMac.a(GenericMultipleBarcodeReader.o)
"std::basic_stringbuf<char, std::char_traits<char>, std::allocator<char> >::str() const", referenced from:
  zxing::BitMatrix::description() in libAGKMac.a(BitMatrix.o)
  zxing::common::CharacterSetECI::getCharacterSetECIByValue(int) in libAGKMac.a(CharacterSetECI.o)
  zxing::common::ECI::getECIByValue(int) in libAGKMac.a(ECI.o)
  zxing::GridSampler::checkAndNudgePoints(zxing::Ref<zxing::BitMatrix>, std::vector<float, std::allocator<float> >&) in libAGKMac.a(GridSampler.o)
  zxing::GF256Poly::description() const in libAGKMac.a(GF256Poly.o)
  zxing::LuminanceSource::operator std::string() in libAGKMac.a(LuminanceSource.o)
  zxing::oned::Code128Reader::decodeRow(int, zxing::Ref<zxing::BitArray>) in libAGKMac.a(Code128Reader.o)
  ...

The full output of the error log can be found here: https://gist.github.com/JamEngulfer/afadadb2bd23121b6bba

JamEngulfer
  • 747
  • 4
  • 11
  • 33
  • You need to recompile AppGameKit with the same language and standard library configuration. – paddy Jul 27 '15 at 00:28
  • Ah. That's not an option for me. The library comes precompiled, as it's a paid-for closed source product. – JamEngulfer Jul 27 '15 at 01:03
  • Why did you choose to use `libc++` then? You could use `libstdc++` instead. Flags: `-std=c++11 -stdlib=libstdc++ -arch i386 -arch x86_64` – paddy Jul 27 '15 at 02:47
  • Because if I use `libstdc++`, it gives me errors saying that things like smart pointers don't exist. – JamEngulfer Jul 27 '15 at 09:36

2 Answers2

0

This can happen if the libraries you are using were compiled with standard library different from your code. Probably, they were compiled with libstdc++.

To solve the problem, you have to recompile the libraries with libc++ if you can, or see if the binary library using libc++ is available.

Another suspicious thing is i386 architecture mentioned in error message. Are you compiling for 32-bit architecture by any chance? (I am not familiar with Mac development, but I thought that it does not support i386 for a long time?)

Ilya Popov
  • 3,765
  • 1
  • 17
  • 30
  • I am indeed compiling my program as a 32-bit program. This is because the people that made the library refuse to provide a 64-bit version, citing that it is unnecessary. – JamEngulfer Jul 27 '15 at 01:01
  • As a workaroud, you can try installing newer version of GCC using a package manager (I am not a mac user, but I believe you can use 'homebrew'). I don't know if it would work together with XCode, however. – Ilya Popov Jul 27 '15 at 01:07
  • Yeah, I'll check out that option. I probably won't be able to force Xcode to use a different compiler, but I'll have a go. – JamEngulfer Jul 27 '15 at 01:40
0

This isn't going to work w/o a lot of work on your part.

Here's what you've got.

  • AppGameKit 2 (binary only), which is apparently built against libstdc++
  • Your code, which links against AppGameKit 2, so it has to be built
  • A very old version of libstdc++ (from gcc 4.2.1) - that's what Apple ships (and is what AppGameKit 2is almost certainly built with)

That version of libstdc++ is pre-c++11, so it doesn't have any smart pointers (save possibly auto_ptr, but it does have std::tr1 stuff)

You could install a new version (say 4.9) of gcc on your Mac, and build your code with that (and a modern libstdc++) and then link to AppGameKit 2. That will probably work, but any problems in that setup will be ... difficult to debug. I don't recommend it.

Alternately, you can use std::tr1::shared_ptr, but that's not a good long-term solution, either.

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45