Linker errors when using a c++/Objective C++ library - c++

I am trying to build a static library for iOS. I have 4 C++ classes with Objective-C++ wrappers. It seems to be building fine but when I try to run my unit tests I get a bunch of linker errors similar to the one below. Is there some command I need to add in order to use my library?
(null): "std::__1::__vector_base_common<true>::__throw_length_error() const", referenced from:
edit:
I solved this by adding the libc++.dylib framework to both targets.

A hunch: The library and the unit test targets disagree on which C++ Standard Library they use. Double check the build setting in both targets.
In Xcode 4.6 the setting is found under the heading "Apple LLVM compiler 4.2 - Language"
In Xcode 5 the setting is found under the heading "Apple LLVM 5.0 - Language - C++"
In both cases the setting is named "C++ Standard Library" (duh!) and the two targets should agree on whether they use libstdc++ or libc++.

Related

LLVM symbol lookup difficulties

I'm following along with the tutorial LLVM provides to get familiar with its IR that can be found here.
Unfortunately, it seems that when I add in the JIT support, the linker has some difficulty following along. Namely, I get a number of undefined symbols,
Undefined symbols for architecture x86_64:
"_LLVMInitializeX86AsmParser", referenced from:
llvm::InitializeNativeTargetAsmParser() in lexer.cc.o
"_LLVMInitializeX86AsmPrinter", referenced from:
llvm::InitializeNativeTargetAsmPrinter() in lexer.cc.o
etc.
I'm building using CMAKE using the LLVM config and can find the headers in my include directories, so I'm unsure why the symbols can't be fine. My code is here, but isn't too specific to the problem. I'm on MacOS.
How can I make the linker find the header files or why is it not working?
If you are using CMake, you need to add some LLVM components. Here is an excerpt from my CMakeLists.txt for the same chapter.
llvm_map_components_to_libnames(llvm_libs analysis core executionengine instcombine object orcjit runtimedyld scalaropts support native)
Relevant links:
The official CMakeLists.txt for the chapter
A StackOverflow question about a similar problem
The example CMakeLists.txt from the documentation

Building a Unity exported Xcode project with LLVM and libc++

I'm currently attempting to build an Xcode project exported from Unity with LLVM against libc++ (the LLVM C++ standard library). The project compiles and links against libstdc++ (the GNU C++ standard library).
If I include "/usr/lib/libstdc++.dylib" amongst the Other Linker Flags this resolves most of the issues but leaves one problem:
Undefined symbols for architecture i386:
"__Z21UnityKeyboard_GetTextPSs", referenced from:
__ZNK16KeyboardOnScreen7getTextEv in libiPhone-lib.a(iPhoneKeyboard.o)
It seems to be looking for the method void UnityKeyboard_GetText(std::string* text) as part of Keyboard.mm.
When I dump the symbols for Keyboard.o I get
00002900 T __Z21UnityKeyboard_GetTextPNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE
000161c0 S __Z21UnityKeyboard_GetTextPNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE.eh
So the mangled names seem to be incompatible when I use libc++. Is there any possible of way of resolving this issue?

Trouble linking C++ with Xcode 5

So I have this legacy project, which I am trying to bring to iOS 7 and Xcode 5. And by legacy, I mean real legacy. Like 2004 legacy.
Anyhow, I am trying to build this thing, and it spits out a few libraries, including some common third party libs. When linking, I get errors like these:
Undefined symbols for architecture ${arch}:
"google::protobuf::internal::WireFormatLite::WriteBytes(int, std::string const&, google::protobuf::io::CodedOutputStream*)"
Upon examination with nm, the old (arm only) binary library still included in the project contains this:
U __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPNS0_2io17CodedOutputStreamE
00000a8c T __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPNS0_2io17CodedOutputStreamE
00002b28 S __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEPNS0_2io17CodedOutputStreamE.eh</code>
The new library (universal), created when I run the project through Xcode 5 (and thus, clang/llvm) contains this:
U __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKSsPNS0_2io17CodedOutputStreamE
00000514 T __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKSsPNS0_2io17CodedOutputStreamE
00000b2c S __ZN6google8protobuf8internal14WireFormatLite10WriteBytesEiRKSsPNS0_2io17CodedOutputStreamE.eh
To me, it looks like the parameters are missing in the mangled name.
Is this normal and I need to look somewhere else?
Or if this is the problem: Any idea how to solve it?
EDIT: I mixed up OLD and NEW. I left the original post unchanged
The old, arm only libary seems to indicate:
google::protobuf::internal::WireFormatLite::WriteBytes(int, std::string const&, google::protobuf::io::CodedOutputStream*)
Which has all the hallmarks of being compiled with libstdc++.
The new universal library indicates:
google::protobuf::internal::WireFormatLite::WriteBytes(int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, google::protobuf::io::CodedOutputStream*)
This has all the hallmarks of being compiled with libc++
Your link error indicates that there is a problem finding:
google::protobuf::internal::WireFormatLite::WriteBytes(int, std::string const&, google::protobuf::io::CodedOutputStream*)
This would be the case if the code linking to the library was compiled using libstdc++ and, because your new universal library is compiled using libc++ the code will not link.
You have to compile everything with the same libc++/libstdc++ support, you cannot mix and match as they will refuse to link. Make sure that every element in your project is compiled using the same C++ Standard Library and the link error should be resolved.
In general, demangling the symbols (using c++filt) allows you to see the proper signatures, and in the case of this code, once you start seeing std::__1:: in the symbols, it indicates that the library was compiled using libc++, and when you see the link failing with unadorned std:: symbols (i.e. without the inner __1::), then it indicates that the item performing the linking is using libstdc++.
Are you perhaps mixing and matching SDKs or compilers? Name mangling might differ between compilers. The only other thing I know that might affect name mangling is the 'extern "C"' keyword, but that usually turns it off completely, so I don't think that's it.
So, if the old code was still built with GCC 2.x and your new code is clang-built, they probably just mangle differently.
Does the error message really say $(arch) ? Not a particular architecture? If it gave a concrete architecture, I'd expect that you have one project that builds e.g. for arm5 and arm6, linking in a library that only has one of these architectures. Then it usually complains about the symbols in that library not being available, I think.

Link iOS app against both libstdc++ and libc++

Use case: I want to use a 3rd party static library that uses libstdc++ (cannot be changed), so I have to link my app against libstdc++. Now if I want to use C++11 features in my own code, I'd have to select libc++ in Xcode and additionally link against libstdc++ to satisfy the static library.
My problem is that even though I selected libc++ in "Build settings" and added "-lstdc++" to "Other linker flags" (also tried via "Build phases > Link Binary With Libraries"), I'm getting linker errors for the latter, that is for libstdc++ functions/classes referenced by the 3rd party lib.
How can I configure the project to link against both C++ standard libraries? It should theoretically be possible since libc++ will be in its own inline namespace std::__1.
I just ran into this , and my solution was that instead of adding -lstdc++ on the other flags, that you put /usr/lib/libstdc++.dylib.
My hunch is that when xcode/clang has -std=c++ set, the older .dylib needs to be explicitly loaded.

link error __stack_chk_fail (using libs with xcode)

I'm trying to compile a C++ app in xcode using gcc 4.0 and and the 10.4u SDK.
I get the following linker error.
"_stack_chk_fail", referenced from:
_read_frame_ in libAudioDecoder.a(stream_decoder.o)
_read_metadata_ in libAudioDecoder.a(stream_decoder.o)
"_stack_chk_guard", referenced from:
___stack_chk_guard$non_lazy_ptr in libAudioDecoder.a(stream_decoder.o)
(maybe you meant: ___stack_chk_guard$non_lazy_ptr)
ld: symbol(s) not found
Other help threads suggest that all I need to do is add...
-fno-stack-protector
...to the 'Other C Flags', which is what I've done, but the problem persists. I've done cleans, rebuilds and even restarted XCode (because it's been known to get confused sometimes), but the problem persists.
Note that libAudioDecoder is my own library that I'm trying to link with. stream_decoder.o is apart of the FLAC library which libAudioDecoder links to.
Essentially my project links with libAudioDecoder which links with libFlac, where libFlac has also been compile using an xcode project.
For each three xcode projects, I'm using gcc 4.0 and and the 10.4u SDK and have 'Other C Flags' and 'Other C++ Flags' set with -fno-stack-protector.
I'm all out of ideas at the moment, so would appreciate some help with this.
Cheers.
Symbol _stack_chk_fail is referenced from symbol _read_frame_ in your libAudioDecoder.a library, not the Xcode project from which you are linking against libAudioDecoder.a. Try to go back and rebuild libAudioDecoder.a with the -fno-stack-protector flag?
It sounds like you may have compiled the library linking against a newer version of libc and are now compiling with an older version, or some other mismatch like that. Searching for "_stack_chk_fail" on StackOverflow will lead you to a ton of other tips.