Conditionally link i386 or armv7 depending on need - objective-c

I have an Xcode project that is currently using Apache Cordova's static library. I'd like to be able to run this on the simulator as well as on iOS devices. I've currently added the two different libraries to the Xcode project (one that supports i386 and one that supports armv7), but I can't seem to figure out how I would tell the linker which one to link. Up until now I've been using "Other Linker Flags" to tell it the path to the Cordova library.
How would I tell the linker the version of the library it should be using?

I've figured this out
What you have to do is add the two different static libraries to the project. Then remove them from the normal build phases and possibly your source file search locations underneath build settings. Then you have to go to other linker flags, click on debug or release and click on "Add Build Setting" -> "Conditional Build Setting" in the bottom right. It will pop up an new build setting for which you can specify the platform underneath which it should be linked in. You have to add the two architectures for both debug and release if you want it to work.
Check out Apple's tutorial.

Related

Undefined symbols for architecture x86_64 for mac

I used podofo library for mac application development, while building demo app i am getting following errors.
The error messages seem to indicate that you are working with static libraries (.a libraires). So, when building your demo app, you need to link with all the librairies needed, including the ones needed by freetype and fontconfig. These are bz2, z, crypto (from the openssl distribution) and others...
If Podofo is built with cmake, you can look at the CMakeCache.txt file. It contains the path where each library Podofo depends on was found on your system.
The bz2 library is not listed in the CMakeCache.txt. It is there by default, so you may just add
-lbz2
to the "Other Linker Flags" in your Xcode project build settings.

XCode won't compile due to armv7s slice error [duplicate]

I upgraded Xcode version and when using external static libraries, I get this message:
ld: file is universal (3 slices) but does not contain a(n) armv7s slice: /file/location for architecture armv7s
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Is there any way to bypass this and add support to the library if the developer of the library hasn't updated their library yet?
If you want to remove the support for any architecture, for example, ARMv7-s in your case, use menu Project -> Build Settings -> remove the architecture from "valid architectures".
You can use this as a temporary solution until the library has been updated. You have to remove the architecture from your main project, not from the library.
Alternatively, you can set the flag for your debug configuration's "Build Active Architecture Only" to Yes. Leave the release configuration's "Build Active Architecture Only" to No, just so you'll get a reminder before releasing that you ought to upgrade any third-party libraries you're using.
I've simply toggled "Build Active Architecture Only" to "Yes" in the target's build settings, and it's OK now!
Try to remove armv7s from project's "Valid architecture" to release from this issue for iOS 5.1 phone
I just posted a fix here that would also apply in this case - basically, you do a hex find-and-replace in your external library to make it think that it's ARMv7s code. You should be able to use lipo to break it into 3 static libraries, duplicate / modify the ARMv7 one, then use lipo again to assemble a new library for all 4 architectures.
Flurry Support for iPhone 5 (ARMv7s)
As I mentioned in yesterday’s post, Flurry started working on a version of the iOS SDK to support the ARMv7s processor in the new iPhone 5 immediately after the announcement on Wednesday.
I am happy to tell you that the work is done and the SDK is now available on the site.
use menu Project -> Build Settings ->
then remove armv7s from the"valid architectures".
If standard has been chosen then delete that and then add armv7.
In case this happens to someone. I built my own library to use with a third party code. While I was building it to deliver, I accidentally left my iPhone 4S plugged in, and so Xcode built my library only for the plugged architecture instead of following the project settings. Remove any plugged in devices and rebuilt the library, link it, and you should be all right.
Hope it helps.
In my case, I was linking to a third-party library that was a bit old (developed for iOS 6, on XCode 5 / iOS 7). Therefore, I had to update the third-party library, do a Clean and Build, and it now builds successfully.

Linker error for imported header file Xcode 4.5

I have downloaded a header file and static library file (.a file) from the internet. They are provided by the wireless printer which i bought for my iphone and trying to make print functionality working in my app. The problem is when I run the sample app provided by them to test printer, I get the following linker error...Obviously the app was designed in the previous versions of Xcode and Im using Xcode 4.5. Much appreciated if someone could Guide me..
If you are building an iOS project and it's using the i386 architecture, then you must be building for the simulator. What happens when you build for an actual iOS device?
It's possible that the library was compiled only for the processor architectures for real iOS devices, typically armv6, armv7, or armv7s. You can use the file command in Terminal to see what architectures are in the .a library file.
Check these answers Symbols not found for architecture i386? and symbols not found.
Check your project-> build phases -> Link Binary With Libraries whether there is libwspr240.a file is there or not.
Remove libwspr240.a file and then readd it using
Project --> Build Phases --> Link Binary with Libraries click '+' button to add.
Then Clean and Build the project

Xcode: how to build a static library project correctly?

This question will be easy for Xcode pros but for a MonoTouch developer it seems to be impossible to resolve. :-)
I'm using Xcode 4.5 and I want to target iOS 5.1 and above and iOS Simulator 5.1 and above.
I have a a library project here and it is coming with a prebuilt binary named "DemoLib" (no extension and it is 11MB in size). The library is a fat lib for Simulator and iOS 5.1+.
I can use that library without any problem.
However if I try to build the library myself, I end up with a "DemoLib.a" file (notice the extension and the size of 30MB). How can I get the same build result? What is a .a file compared to the file without extension?
I tried to build the project "for running", and "for archiving" in Xcode. Both results in the same 30MB .a file.
I was expecting some dropdown in Xcode where one could select "DEBUG" or "RELEASE" build and the latter one would create the smaller lib.
Of course I could never tell without seeing the framework's project file. Having said that, there is an excellent guide to creating and compiling iOS frameworks here: https://github.com/jverkoey/iOS-Framework
Using the above guide, you should be able to recreate your framework's project from scratch, add the files you have to it, and properly compile it.
Hope this helps! :)
Did it come with a Makefile? Create a new target, set the build settings of the target to what's in the Makefile, then set your project to depend on that new target.
A file with the .a is a static library, which means it depends on nothing external and all the code it needs is compiled inside it. I think no extension generally implies dynamic library, which means it'll depend on some dependencies being present on your system to link against. Maybe that's why the .a is so much bigger. I think Xcode will build static by default because iOS does not allow the use of dynamic libraries.
The dropdown for what to build is in your scheme. Command+shift+< to view your scheme. Within the scheme you can edit which environment each method of building will use.

Adding a framework to XCode 4

of course i did research before posting my question.
I looked at
How to "add existing frameworks" in Xcode 4?
Adding Framework in Xcode 4
Adding an OpenGL framework in Xcode 4
XCode 4 adding dylib
but whole thing is becoming wrong.
My goal: Add (CorePlot) framework to XCode Mac project (not an iPhone one)
My environment: OSX Lion 10.7, SDK Lion, XCode 4.1 (4B110)
My steps:
Opened XCode, created new project
Downloaded CorePlot into my libraries directory (like ~/Applications/LIBS)
Opened project preferences, via (+) opened dialog to add framework
Add existing framework (+ copy files to dest. group if needed)
Selected directory was ~/Applications/LIBS/CorePlot/Binaries/MacOS/CorePlot.framework/
DnD CorePlot to Frameworks Group
Added CorePlot to Build Phases > Link Binary with Libraries
and ran my project
what I got is this error message:
dyld: Library not loaded: #loader_path/../Frameworks/CorePlot.framework/Versions/A/CorePlot
Referenced from: /Users/username/Library/Developer/Xcode/DerivedData/metralight-hjuvuwlhgohrtdeepvcymnsaxomc/Build/Products/Debug/metralight.app/Contents/MacOS/metralight
Reason: image not found
And in fact, when I looked into given directory (app bundle) there was no directory Frameworks and so the linking cannot be successful
I have searched one more, and found, that I can create Build Rule and copy files into final binary bundle via some script, but is this only way how to do this?
Isn't there some option to just turn on/off copying linked frameworks to final bundle?
Note that CorePlot target '.framework' has Dynamic Library Install Name set to #loader_path/../Frameworks/CorePlot.framework/Versions/A/CorePlot, so it is looking in right place in final binary bundle
After adding framework via "Add existing framework"
Go to Project Settings > Build Phases
In right bottom corner click Add buid phase > Copy Files
Select Destination > Frameworks
Drag&Drop framework to files list
And that's it.
Another important detail here - you must have the "Runtime search path" to be defined in the projects, it's empty by default.
Something like this:
LD_RUNPATH_SEARCH_PATHS = #loader_path/../Frameworks