Making a static library is a good idea if you have lots of code you will be reusing or code that you want to isolate and wrap up. For iPhone projects we need to deal with the fact that there are two architectures that the library might possibly be running on: the Simulator (x86) and the Real Hardware (arm). The Apple iPhone SDK does this by switching between two folders, one to support the Simulator and the other to support the real device. I have not been able to find a way to mimic this for our own libraries.

Hybrid library (x86 / arm)

However, with a tool called “lipo” it is possible to “concatenate” two versions of a library into one file, so there is no need for switching. The same library then just works in the Simulator and on a real iPhone. Here is an example of how to set up a target in Xcode to automagically build the x86 and arm versions of an existing library target and glue them together into a hybrid library:

Start with your existing library target

I have a library target here called “myAwesome” that I want to build for both architectures.

Library Target "myAwesome"

Duplicate it

Duplicate the target. This is probably the easiest way to create a derivative of an existing target. We want to keep all the build settings intact. Perhaps give it a fancy name like “myAwesome X-Platform”.

Duplicate Library Target

Add a Run Script

Right click on the newly created target and choose “Add” -> “New Build Phase” -> “New Run Script Build Phase”.

Add New Build Phase: "Run Script"

The Script

A window will pop-up where the run script can be inserted and edited. Download the cross platform build script here.

Edit Script

Delete All Other Phases

We don’t need the other phases from the duplicated target. Just delete them.

# Settings:
# Path to store the x-platform lib and header files:
MY_LIBS_PATH=”$DEVELOPER_DIR/myLibs/”
# Name of the library target:
MY_TARGET=”myAwesome”
# Build for Simulator and Device:
xcodebuild -target $MY_TARGET -sdk iphonesimulator3.0 -activeconfiguration
xcodebuild -target $MY_TARGET -sdk iphoneos3.0 -activeconfiguration
# Make new folder if it doesn’t exist:
mkdir -p “$MY_LIBS_PATH/lib$PRODUCT_NAME-$CONFIGURATION”
# Concat the libraries with lipo:
$PLATFORM_DEVELOPER_BIN_DIR/lipo -arch arm “$BUILD_DIR/$CONFIGURATION-iphoneos/lib$PRODUCT_NAME.a” -arch i386 “$BUILD_DIR/$CONFIGURATION-iphonesimulator/lib$PRODUCT_NAME.a” -create -output “$MY_LIBS_PATH/lib$PRODUCT_NAME-$CONFIGURATION/lib$PRODUCT_NAME.a”
# Copy public headers:
cd “$BUILD_DIR/$CONFIGURATION-iphoneos/$PUBLIC_HEADERS_FOLDER_PATH”
cp *.h “$MY_LIBS_PATH/lib$PRODUCT_NAME-$CONFIGURATION/”
# Clean up temp dirs:
# rm -r “$BUILD_DIR”
# Show in library finder:
open “$MY_LIBS_PATH/lib$PRODUCT_NAME-$CONFIGURATION/”
exit 0

Delete All Other Phases

Build!

Now before pressing “Build”, make sure the current configuration is set to “Device” and not to “Simulator”. The “lipo” tool is only part of the Device SDK, so the script will break if you try to build in the Simulator configuration.