I have so far used Google APIs Client Library for Objective-C by compiling the source files directly into my app (as described here). If I were to switch over to linking to the iOS static library (as also described here), how would this insure that the code works on different architectures?
For instance, if I follow the verbatim instruction I have to compile the static library by choosing a schema (GTLTouchStaticLib) and an architecture (e.g. iOS Simulator: iPhone 5). If I choose a simulator as architecture, file libGTLTouchStaticLib.a reports that the archive contains code for architectures i386 and x86_64. If I choose a physical iPhone 5 instead, file reports on architectures armv7 and arm64.
How do I ensure that the libGTLTouchStaticLib.a that I'm going to drag into my application project's Build Phases "Link Binary with Libraries" list (according to Google's instructions) contains all (not just some) of the architectures that might be encountered when my app goes life? I guess armv7 and arm64 is sufficient for an app that requires iOS 8, but I'd like to be sure.)
You have to combine the generated binaries using lipo command line tool.
The following tutorial about creating static library in iOS demonstrates use of lipo under section Universal Binaries
Related
.
Hello, all.
I noticed some strange thing.
As all you know there are a lot of complaints regarding "unsupported architecture" error message during validation against App Store when using 3rd party frameworks with i386 slice (for example).
I've upgraded xCode to 6.2 and now I have following situation:
I built some simple Single-View application (iPhone) that's using two external custom frameworks (that I built too).
One of the frameworks is 'Cocoa Touch Static Library" that was converted to the framework (using custom script) with two '.a' files (iphoneos and iphonesimulator configurations) combined into one fat binary (using lipo).
The second framework is "Cocoa Touch Framework" (actually, its static version - via Mach-O build settings), with two binary frameworks combined to one fat binary (using lipo too).
When I check both contained-in-framework binaries with "lipo -info" I get - "armv7 i386 x86_64 arm64" in case of first framework and "i386 x86_64 armv7 armv7s arm64" in case of the second one (second framework was built intentionally (manually) with these architectures).
When I archive my app and try to validate it from Organizer - it passes successfully.
When I check the application binary (from the xCode archive folder) with "lipo -info" I get "armv7 arm64" - so now it's clear why no error message is displayed during app validation.
Have any of you seen such behavior?
May Apple fix this issue in xCode 6.2?
I'm going to test it tomorrow with old xCode version (6.1.1) anyway.
Any input is more than welcomed.
Thank you.
I have a static library that I've been integrating into my Unity-iOS projects for several months now. Everything has been working fine for Unity 4.3.x.
With the recent release of Unity 4.6.3, which provides building for 64-bit devices using the IL2CPP scripting backend and Universal architecture, my static library no longer works. I have a built a very simple sample app with Unity using just the static library and it crashes at runtime.
SDKTestApp(11555,0x199dff310) malloc: *** error for object 0x174287f2f: Invalid pointer dequeued from free list
*** set a breakpoint in malloc_error_break to debug
Note that the project compiles just fine, but shortly after the app loads and some static library functions are executed, it crashes. And this is only problematic with those devices that are 64-bit only (iPhone 6, iPad Air, etc.).
Finally, here is the output when I run lipo -info myStaticLibrary.a on the (.a) file:
myStaticLibrary.a: Mach-O universal binary with 3 architectures
myStaticLibrary.a (for architecture arm64): current ar archive random library
myStaticLibrary.a (for architecture armv7s): current ar archive random library
myStaticLibrary.a (for architecture armv7): current ar archive random library
Any ideas?
Turns out it had nothing to do with my Xcode settings, and in fact, my Xcode settings were correct. This was a bug related to my specific code.
For future reference, the lipo -info myStaticLib.a is incredibly useful to determining architecture support.
I want to create a universal static library, say called sampleStaticLib.a, which gets included in an app called HelloWorld. The HelloWorld app needs to use the APIs defined in the static library, and needs to work on both iOS simulator and iOS device. I understand from various posts in the Internet that I can accomplish this by using the lipo tool to aggregate the static libraries of both the simulator and device into a universal library, and then include the universal library inside the HelloWorld.xcodeproj.
However, alternatively, if I do the following:
simply set the valid architecture in the static library xcodeproject
(sampleStaticLib.xcodeproj) to "armv7 armv7s arm64 i386 x86_64
generate the sampleStaticLibrary.a
include it in the HelloWorld.xcodeproj
My expectation is that, since I set the valid architecture of 'sampleStaticLib' to all architectures spanning x86 and ARM, the library should work on both simulator and device. But it doesn't work on the simulator.
So, can't setting a broad "valid architecture" replace the need to use 'lipo tool' while creating universal static libraries?
No, unfortunately, that is not possible as trivially as you would like.
The reason is that when you build your project, it will build with the selected SDK for all of the requested architectures. The iOS SDK supports ARM, and the iOS Simulator SDK supports Intel. You need to build the ARM slices against the iOS SDK and the Intel slices against the iOS Simulator SDK and then lipo them together into a universal binary.
It should work. For instance, this static library
https://github.com/cocos2d/cocos2d-x-3rd-party-libs-bin/blob/v3/png/prebuilt/ios/libpng.a
It has armv7, armv7s, arm64, i386 and x86_64 binaries.
$ file libpng.a
libpng.a: Mach-O universal binary with 5 architectures
libpng.a (for architecture armv7): current ar archive random library
libpng.a (for architecture armv7s): current ar archive random library
libpng.a (for architecture i386): current ar archive random library
libpng.a (for architecture x86_64): current ar archive random library
libpng.a (for architecture cputype (16777228) cpusubtype (0)): current ar archive random library <-- It's arm64
Xcode(Clang toolchain) can link this static library for iOS device and also iOS simulator. And no problems at all.
But it doesn't work on the simulator.
What do you mean? I recommend you to update the question about it more detail.
I have a Xcode project, that includes a Static Library project, that uses another static library that does not support the iOS simulator architecture (Vuforia SDK: libQCAR.a).
Vuforia SDK documentation states:
Vuforia applications must be deployed to a device to run; they cannot be run in the iOS simulator.
This is my project structure:
MyApp.xcodeproj
Classes
MyStaticLibrary.xcodeproj
Classes that depends on libQCAR.a
Frameworks
libMyStaticLibrary.a
libQCAR.a
My problem is that MyApp.xcodeproj does not build for the iOS Simulator because libQCAR.a is not built for the i386 architecture.
Is there anyway to make MyApp.xcodeproj ignore the libQCAR.a library when building for i386? I would be able to disable all the code that depends on the library with #if !(TARGET_IPHONE_SIMULATOR)
You can use a conditional build settings to specify the library you want to link only on a given platform, instead of adding the library to your project in the usual ways. Specifically, you will need to specify:
-lQCAR
in "Other Linker Flags".
Have a look at the attached image that should make things more clear (in the picture I am linking only for the simulator, you will want to select a device, I guess).
Also, do not forget to add the path to the directory containing the library to "Library Search Path" build setting (this does not need to be conditional; it would not do any harm on the simulator).
This issue seems very similar to: Xcode: Conditional Build Settings based on architecture (Device (ARM) vs Simulator (i386))
I believe sergio's solution is very close, but have you tried specifying the full path to the library under Other Linker Flags (potentially without "-l" - just the path)?
In my case, it should specify clearly which SDK uses which flags.
So in Any iOS Simulator SDK, you should not include the library.
In Any iOS SDK, you should include it. In my case, it's -lCloudReco.
I'm trying to use the facebook-ios-sdk in an iPhone application. I followed the setup instructions and it works perfectly on the simulator, but I cannot get it to run on my actual device. I am using Xcode 4.3 and my deployment target is 3.1 (with ARC).
When I try to run the application on the device, it complains that it cannot link the facebook-ios-sdk since the statically linked library (as per suggestion when using ARC) does not support armv6? According to the facebook-ios-sdk page it does however support it.
Is there a different way to compile the linked lib than described on the facebook-ios-sdk page to include armv6?
Open facebook-ios-sdk.xcodeprodj, then in Build Settings -> Architectures add armv6.
Build/rebuild the static library via the included script:
./scripts/build_facebook_ios_sdk_static_lib.sh
The Library should now work with armv6 and armv7
In addition to what rogchap mentioned, is the value of Valid Architectures "armv6 armv7" in the Build Settings for your facebook-ios-sdk project?
And just to be sure, my Architectures setting reads as follows without the quotes:
"armv6 $(ARCHS_STANDARD_32_BIT)"
Another hint: check your info.plist file for the key 'required device capabilities' and make sure that there is no value like 'armv7'. That would exclude armv6 devices.