Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Errors when cross compiling C++/Objective-C++

I have a C++ library being referenced by an Objective-C++ project. The library compiles fine on its own and the Objective-C++ project compiles fine until I instantiate the first class from the library (using an object pointer). Before using the class from my library I had references to stl string objects that didn't cause problems.

I'm getting the following errors:

Undefined symbols for architecture i386:
  "std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)", referenced from:
      __verify_callback_c in *************.a(cxx_db.o)
      DbEnv::_stream_message_function(__db_env const*, char const*) in *************.a(cxx_env.o)
      DbEnv::_stream_error_function(__db_env const*, char const*, char const*) in *************.a(cxx_env.o)
  "std::basic_ios<char, std::char_traits<char> >::fail() const", referenced from:
      __verify_callback_c in *************.a(cxx_db.o)
  "std::ios_base::Init::Init()", referenced from:
      __static_initialization_and_destruction_0(int, int) in *************.a(cxx_db.o)
      __static_initialization_and_destruction_0(int, int) in *************.a(cxx_dbc.o)
      __static_initialization_and_destruction_0(int, int) in *************.a(cxx_dbt.o)
      __static_initialization_and_destruction_0(int, int) in *************.a(cxx_env.o)
      __static_initialization_and_destruction_0(int, int) in *************.a(cxx_mpool.o)
      __static_initialization_and_destruction_0(int, int) in *************.a(cxx_txn.o)
      __static_initialization_and_destruction_0(int, int) in *************.a(cxx_lock.o)
      ...
  "std::ios_base::Init::~Init()", referenced from:
      ___tcf_0 in *************.a(cxx_db.o)
      ___tcf_0 in *************.a(cxx_dbc.o)
      ___tcf_0 in *************.a(cxx_dbt.o)
      ___tcf_0 in *************.a(cxx_env.o)
      ___tcf_0 in *************.a(cxx_mpool.o)
      ___tcf_0 in *************.a(cxx_txn.o)
      ___tcf_0 in *************.a(cxx_lock.o)
      ...
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

So far I've found that errors like these can be caused by:

  1. Having a file type of .m instead of .mm
  2. Creating a C++ object in my Objective-C++ without using a pointer

I'm assuming it's some sort of cross-compile error, but I don't know where to look. Ideas on what it could be?

EDIT:

Build Settings:
C++ Standard Library = libc++
C++ Language Dialect = c++0x

These are in my top-level project. The contained library is using these as well (it references an outside library as well, and the header path was no longer found when added it to my main project - I had to add it to my main project settings).

Edit 2: Here is the build step that fails:

Ld /Users/user/Library/Developer/Xcode/DerivedData/BerkeleyDBHelloWorldSimulator-bgnkrqnronvtkoaongfsdturoklb/Build/Products/Debug-iphonesimulator/BerkeleyDBHelloWorldSimulator.app/BerkeleyDBHelloWorldSimulator normal i386 cd /Users/user/Documents/Projects/Tests/BerkeleyDBHelloWorldSimulator setenv MACOSX_DEPLOYMENT_TARGET 10.6 setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin" /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/clang++ -arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk -L/Users/user/Library/Developer/Xcode/DerivedData/BerkeleyDBHelloWorldSimulator-bgnkrqnronvtkoaongfsdturoklb/Build/Products/Debug-iphonesimulator -F/Users/user/Library/Developer/Xcode/DerivedData/BerkeleyDBHelloWorldSimulator-bgnkrqnronvtkoaongfsdturoklb/Build/Products/Debug-iphonesimulator -filelist /Users/user/Library/Developer/Xcode/DerivedData/BerkeleyDBHelloWorldSimulator-bgnkrqnronvtkoaongfsdturoklb/Build/Intermediates/BerkeleyDBHelloWorldSimulator.build/Debug-iphonesimulator/BerkeleyDBHelloWorldSimulator.build/Objects-normal/i386/BerkeleyDBHelloWorldSimulator.LinkFileList -mmacosx-version-min=10.6 -Xlinker -objc_abi_version -Xlinker 2 -stdlib=libc++ -Xlinker -no_implicit_dylibs -D__IPHONE_OS_VERSION_MIN_REQUIRED=50000 -lstdc++ /Users/user/Library/Developer/Xcode/DerivedData/BerkeleyDBHelloWorldSimulator-bgnkrqnronvtkoaongfsdturoklb/Build/Products/Debug-iphonesimulator/libBerkeleyDB.a -framework UIKit -framework Foundation -framework CoreGraphics -o /Users/user/Library/Developer/Xcode/DerivedData/BerkeleyDBHelloWorldSimulator-bgnkrqnronvtkoaongfsdturoklb/Build/Products/Debug-iphonesimulator/BerkeleyDBHelloWorldSimulator.app/BerkeleyDBHelloWorldSimulator

like image 215
N_A Avatar asked Feb 09 '12 22:02

N_A


2 Answers

It's taken us some time to get to something approaching a solution in the comments thread, so I'm going to summarise it here:

This type of error is caused by not successfully linking to the correct libstdc++.dylib, the standard C++ library. Sometimes, you forget to add it, sometimes XCode gets confused.

First of all, make sure you are indeed linking to it in your app target's settings: it must appear in "build phases", "link binary with libraries".

If it's there, but still failing to link, check the raw build log for any warnings that XCode might be hiding from you: e.g. about wrong architecture. This means you're linking to the wrong version of the file - e.g. linking against the simulator or OSX version instead of that in the iPhoneOSx.y.sdk directory. In the past, with XCode 3, this was really easy to get wrong, and the only way to fix it was to try every single different libstdc++.dylib that XCode offered until one worked. XCode4 normally only offers one, in addition to the names with version numbers. You should normally pick the dylib without a version number.

Make sure all subprojects that may link against libstdc++.dylib use the same version in the same location.

Check the "Library Search Paths" and "Framework Search Paths" for any paths that you didn't add yourself. I've had XCode set paths to old SDKs here, which confused the linker.

Finally, sometimes it helps to just remove the reference to libstdc++.dylib, clean the project, quit and restart XCode, and re-add the reference.

like image 109
pmdj Avatar answered Oct 13 '22 23:10

pmdj


Make sure both your code and the library links against the same C++ standard library.

like image 39
rasmus Avatar answered Oct 14 '22 01:10

rasmus