XCode build fail: C++ lib within iOS lib within (test) consumer app - xcode

I've got three layers:
- core C++ engine
- iOS audio wrapper
- demo iOS consumer project
So I am:
1) compiling engine.a, which links against accelerate framework.
2) compiling wrapper.a, with a dependency on engine and linking against engine.a AND accelerate framework.
So far so good. I can build wrapper.a. But something looks wrong. My wrapper code is using CoreAudio calls. It is fetching real-time microphone data. It should be reporting errors, surely? It should be requiring me to link AudioToolbox or AudioUnit frameworks.
So I don't see why that library even compiles.
3) create a fresh iOS project that links against wrapper.a.
Now I'm getting a 30+ build errors:
```
Undefined symbols for architecture x86_64:
"vtable for std::exception", referenced from:
std::__1::bad_function_call::bad_function_call() in libfftDecoder.a(FFTDecoder.o)
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
"std::__1::__thread_struct::__thread_struct()", referenced from:
std::__1::thread::thread(void (DecoderThread::&&)(), DecoderThread&&) in libfftDecoder.a(FFTDecoder.o)
"std::__1::__throw_system_error(int, char const*)", referenced from:
std::__1::thread::thread(void (DecoderThread::&&)(), DecoderThread&&) in libfftDecoder.a(FFTDecoder.o)
:
```
Can anyone suggest what might be the problem? That first error kind of looks like 'failing to process a C++ construct'.
I should mention that Xcode is very disappointing in the context of this task. The items I link against in the 'build phases' tab are not consistently reflected in the project navigator's "frameworks" folder for the respective project. Also sometimes a .a appears red even when it built successfully.

First point (thanks #wiliz on #iphonedev Freenode) is that a static library has no concept of linking against something. So I should be removing all the links from my .a files and putting all of the dependencies in my consumer app.
The problem was that the library contains compiled C++ code. And the consumer app doesn't have any .mm files. So it isn't using ObjC++ anywhere. So it isn't linking against the C++ stdlib.
Simply renaming one of the .m files (say ViewController.m) to .mm fixes the problem.

Related

Binding a static library into a Xamarin iOS project

I've decided to take a step back and just try to get a very simple proof of concept to work.
I've progressed a little further thanks to one of the Xamarin Lightning Lectures around this topic. I’ve been following this tutorial:
https://university.xamarin.com/lightninglectures/ios-bindings-in-cc
Here’s what I’ve done so far:
1) I have a simple C file “example.c” with 3 functions: addOne(int n), subtractOne(int n), get_time()
2) As shown in the tutorial, I used SWIG to create a C wrapper class - “example_wrap.c” (along with the C# wrapper classes).
3) I created the static library in Xcode and built a FAT binary with all architectures (lipo used to combine libs).
The tutorial talks about creating 2 projects - one with the C# wrapper classes and the other a single view iOS app. The iOS project has the libexample.a static library(as a BundledResource). Everything was going well until trying to build the iOS app. I can't get the iOS app to compile. I've removed any calls to the static library for now to isolate the issue....I'm just trying to get it to compile and link correctly. So all I have now is just a blank iOS app with the bundled static library. But I'm still having problems.
I have the following added to the mtouch arguments:
-cxx -gcc_flags "-L${ProjectDir} -lexample -force_load ${ProjectDir}/libexample.a"
When compiling, I get these errors:
Undefined symbols for architecture x86_64:
"subtractOne(int)", referenced from:
_CSharp_subtractOne in libexample.a(example_wrap.o)
"addOne(int)", referenced from:
_CSharp_addOne in libexample.a(example_wrap.o)
"get_time()", referenced from:
_CSharp_get_time in libexample.a(example_wrap.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I double checked the symbols in the libexample.a file by running “nm -arch x86_64 libexample.a” from the command line. It appears that all the symbols are listed for that architecture.
Here’s a link to the zip file with my libexample.a and C files:
https://drive.google.com/open?id=0B2WtJ38rvldKYmlZckU3QjNBeUE
I’m sure this is just a configuration error but I can’t seem to pinpoint where I’m going wrong.
Thanks.
I thought I'd answer my own question here - after getting some help from Xamarin support, it looks like I might have mixed up how I created the static library - I had to make sure the files were compiled as 'C' files, instead of C++. After I generated the static library correctly, the compiler was able to recognize the missing symbols.

Do I need to link libs that dependencies link?

I'm trying to write a simple game engine for iOS in Objective C and C++ using Xcode.
I've made a game project and a game engine project. The latter is added to the former as a subproject. The engine is also added as a target dependency and as a binary to be linked in the game project.
My engine uses CADisplayLink so I add QuartzCore.framework in the engine project's "Link binary with libraries list" (found in Build phases).
Now, when I try to build my game project (the project with the subproject), I get this error:
Undefined symbols for architecture i386: "_OBJC_CLASS_$_CADisplayLink", referenced from: objc-class-ref in libVoya-iOS.a
This error only happens when building from the game project - doing it from the engine project works fine. If I add QuartzCore.framework to the game project building works fine.
Can it really be true I have to specifically require frameworks that one of my target dependencies already have required? In this case: My engine (sub project) already links QuartzCore - is it really necessary to also do this in the projects using this engine? It feels like double work for no reason.
Or perhaps I've just completely misunderstood something? :)
Add QuartzCore framework to fix this issue.
I've now found the answer to my question and I'd like to share it.
Static libraries are nothing more than a grouping of the compiled versions of the library's source files. They do not include any libraries they themselves might depend on.
Fusing all dependencies together happens only when you build the actual executable in the very end. For this reason, your application should indeed link against your dependencies' dependencies.
As for the example in my question, that means that my game should link QuartzCore while my game engine should not (even though it is my GameEngine who is using it).
Learn more here:
Duplicate symbol: Include static lib A in static lib B, also include lib A and B in XCode Project
Linking static libraries, that share another static library
I believe this is because you're using a target dependency instead of linking against a precompiled library.

"Undefined symbols for architecture armv7" when importing STATIC LIBRARY that contains OPENCV functions

I developed a very simple application, using openCV for iOS. It worked fine until I decided to use that code in another project. The new project shows this armv7 error and I can't see where the problem is (please, see the last image).
I created a static lib file with my working code, which has the following architecture info:
Then I compiled it into a *.a file and added the dyOpenCv.a and the DyOpenCV.h files to my main project, which has the following architecture configuration:
But when I try to use the method within the header file DyOpenCV.h I get the following errors:
Any ideas of what may be wrong?
There were two issues related to linking libraries:
Firstly, although my subproject had the opencv2.framework
correctly added and linked to it, I also had to add the framework
to my main project. This way I got rid of the cv::* linking
problems;
The second issue was related to my cross-compiling Objective-C++ configuration. Since I was using libc++ as my Standard Library, I had to add -lc++ to my Other Linker Flags. In case you are using libstdc++ as your Standard Library, you should add -lstdc++ instead.
After those changes, it all worked perfectly!
Good luck!
I think its because ur project is not linking to the C++ runtime .
Try adding libc++.dylib to ur linked Libraries.

std::terminate undefined in Cocoa App

I have a Cocoa app that compiles and links fine. I've since broken out some of the code into a static library and then have gone back and tried to link that libMyLib.a library to my original program.
I now get a linker error
Undefined symbols for architecture x86_64:
"std::terminate()", referenced from:
referencing one of the source modules that use to live in my main project, but now lives in the library.
I've tried to go back and match up each compiler and linker setting to see which one is different, but I just can't seem to nail it down. My hunch is that I'm linking with a C STD and need a C++ STD, but everything is using the C99 compiler with standard libs.
Any ideas?
Thanks!
linking in libc++.dylib fixed the issue

Including one Xcode project in another -- linker errors

I am trying to do this, and running into problems. The parent project needs to access the class SettingsViewController from the child project. I have put the child project path into my header search paths. Everything compiles OK, but I get linker errors, as follows:
Undefined symbols: "_OBJC_METACLASS_$_SettingsViewController",
referenced from:
_OBJC_METACLASS_$_StatisticsViewController in StatisticsViewController.o "_OBJC_CLASS_$_SettingsViewController",
referenced from:
objc-class-ref-to-SettingsViewController in SelectionViewController.o
_OBJC_CLASS_$_StatisticsViewController in StatisticsViewController.o ld: symbol(s) not found collect2: ld
returned 1 exit status
How can I fix this?
I assume the child project is a static library. Currently, your parent project knows how to find the header files of the child project (otherwise it wouldn't compile), but it doesn't know that it has to link to the library (.a) file of the child project.
You should probably add the library file to Targets > {your app} > Link Binary with Libraries. Furthermore, you probably need to add the linker flags -ObjC and possibly -all_load.
There are many detailed descriptions on the net, e.g. Build iPhone static library with Xcode.
Update:
If it's not a static library, then it's a rather strange project setup. The best thing you can do is to add the shared files (.h and .m) to both projects. They will then be independently compiled in both projects. That should work if you have few shared files.
But I recommend anyway to use a project setup with a static library. It nicely works if you properly set it up. I'm successfully using it. And - as I've told before - there a several good descriptions on the net how to set it up.
You may be missing a framework. Can't really tell from what you have posted here though.
I know this is very old but might be helpful for others.
You need to setup the included project in Target Dependencies in "Build Phases" to get the included projet to be compiled and you also should add the static library of the included project in the "Link Binary with Libraries".
Click on your Target->Build Phases and set these up.
Undefined symbols
Undefined symbols is a linker error
1.Check if you have added a library or framework
Project editor -> select a target -> General -> Frameworks, Libraries, and Embedded Content(Linked Frameworks and Libraries)
//or
Project editor -> select a target -> Build Phases -> Link Binary With Libraries
2.If you try to use Swift code from Objective-C
Add empty .swift file to the Objective-C project. When Xcode ask press Create Bridging Header

Resources