It appears that we can - theoretically - build a single static library that includes both simulator and iPhone and iPad.
However, Apple has no documentation on this that I can find, and Xcode's default templates are NOT configured to do this.
I'm looking for a simple, portable, re-usable technique that can be done inside Xcode.
Some history:
- In 2008, we used to be able to make single static-libs that included both sim and device. Apple disabled that.
- Throughout 2009, we made pairs of static libs - one for sim, one for device. Apple has now disabled that too.
References:
This is a great idea, it's an excellent approach, but it doesn't work: http://www.drobnik.com/touch/2010/04/universal-static-libraries/
- There's some bugs in his script that means it only works on his machine - he should be using BUILT_PRODUCTS_DIR and/or BUILD_DIR instead of "guesstimating" them)
- Apple's latest Xcode prevents you from doing what he's done - it simply will not work, due to the (Documented) change in how Xcode processes targets)
Another SO questioner asked how to do it WITHOUT xcode, and with responses that focussed on the arm6 vs arm7 part - but ignored the i386 part: How do i compile a static library (fat) for armv6, armv7 and i386
- Since Apple's latest changes, the Simulator part isn't the same as the arm6/arm7 difference any more - it's a different problem, see above)
I actually just wrote my own script for this purpose. It doesn't use Xcode. (It's based off a similar script in the Gambit Scheme project.)
Basically, it runs ./configure and make three times (for i386, armv7, and armv7s), and combines each of the resulting libraries into a fat lib.
ALTERNATIVES:
Easy copy/paste of latest version (but install instructions may change - see below!)
Karl's library takes much more effort to setup, but much nicer long-term solution (it converts your library into a Framework).
Use this, then tweak it to add support for Archive builds - c.f. @Frederik's comment below on the changes he's using to make this work nicely with Archive mode.
RECENT CHANGES: 1. Added support for iOS 10.x (while maintaining support for older platforms)
Info on how to use this script with a project-embedded-in-another-project (although I highly recommend NOT doing that, ever - Apple has a couple of show-stopper bugs in Xcode if you embed projects inside each other, from Xcode 3.x through to Xcode 4.6.x)
Bonus script to let you auto-include Bundles (i.e. include PNG files, PLIST files etc from your library!) - see below (scroll to bottom)
now supports iPhone5 (using Apple's workaround to the bugs in lipo). NOTE: the install instructions have changed (I can probably simplify this by changing the script in future, but don't want to risk it now)
"copy headers" section now respects the build setting for the location of the public headers (courtesy of Frederik Wallner)
Added explicit setting of SYMROOT (maybe need OBJROOT to be set too?), thanks to Doug Dickinson
SCRIPT (this is what you have to copy/paste)
For usage / install instructions, see below
INSTALL INSTRUCTIONS
...BONUS OPTIONAL usage:
If you can't find the output file, here's a workaround:
Add the following code to the very end of the script (courtesy of Frederik Wallner): open "${CREATING_UNIVERSAL_DIR}"
Apple deletes all output after 200 lines. Select your Target, and in the Run Script Phase, you MUST untick: "Show environment variables in build log"
if you're using a custom "build output" directory for XCode4, then XCode puts all your "unexpected" files in the wrong place.
...that is the location of your Universal Build.
How to include "non sourcecode" files in your project (PNG, PLIST, XML, etc)
Script to auto-copy the built bundle(s) into same folder as your FAT static library:
IOS 10 Update:
I had a problem with building the fatlib with iphoneos10.0 because the regular expression in the script only expects 9.x and lower and returns 0.0 for ios 10.0
to fix this just replace
with
Great job! I hacked together something similar, but had to run it separately. Having it just be part of the build process makes it so much simpler.
One item of note. I noticed that it doesn't copy over any of the include files that you mark as public. I've adapted what I had in my script to yours and it works fairly well. Paste the following to the end of your script.
I have spent many hours trying to build a fat static library that will work on armv7, armv7s, and the simulator. Finally found a solution.
The gist is to build the two libraries (one for the device and then one for the simulator) separately, rename them to distinguish from each other, and then lipo -create them into one library.
I tried it and it works!
There is a command-line utility
xcodebuild
and you can run shell command within xcode. So, if you don't mind using custom script, this script may help you.Maybe looks inefficient(I'm not good at shell script), but easy to understand. I configured a new target running only this script. The script is designed for command-line but not tested in :)
The core concept is
xcodebuild
andlipo
.I tried many configurations within Xcode UI, but nothing worked. Because this is a kind of batch processing, so command-line design is more suitable, so Apple removed batch build feature from Xcode gradually. So I don't expect they offer UI based batch build feature in future.