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.
Related
I created a objective-c library in Xcode 6.1. It supports 64 bit architecture. I added it to an old project with 32 bit support. It is crashing and giving me an error
ld: file is universal (3 slices) but does not contain a(n) armv7s slice
How can i update the library to support the old project?
Remove the support for any architecture armv7s from the project (target) -> Build Settings -> Valid Architectures:
Alternatively, you can set the flag for your debug configuration's
Change Build Active Architecure Only to Yes.
Hope this will work.
you can just add armv7s to the library's Target->Build Settings->Architectures along with ($_ARCHS_STANDARD)
.
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 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
I've integrated the latest iOS facebook SDK (v3.10). I did drag and drop the FacebookSDK.framework into my project and unselect the Copy; now the .ipa file size has increased around 8MB. (ipa with FBSDK = 9.9MB -- without FBSDK = 1.5MB)
I tried their sample code, and did the same thing!! But there is no significant changes on the final ipa file!
What would be the possible issue?
There is no issue. The Facebook iOS framework is just that big. It's big because it's a FAT binary including armv7, armv7s, arm64, i386 and x86_64 architectures.
~ $ lipo -i ./FacebookSDK.framework/Versions/A/FacebookSDK
Architectures in the fat file: ./FacebookSDK.framework/Versions/A/FacebookSDK are:
i386 armv7 armv7s x86_64 arm64
It also contains 1.1MB of images, but the majority of the size is the FAT binary.
You can probably modify the Xcode project to make it not build for the Simulator (x86_64 and i386). But your app probably runs on 4S+, so you'll need to keep armv7, armv7s and arm64.
Unselecting the copy doesn't change much (except maybe the images bundle won't be added to your resources, so no images will show, you don't want that). The file size still increases because your app links the Facebook SDK binary in with its own binary (that's how it is able to use the Facebook code from the SDK).