How to create fat static library for iOS 7, 8 projects

Question

With Xcode I’ve to build static libraries for third party iOS projects with Architectures set to $(ARCHS_STANDARD). Both iOS 7 and iOS 8 applications should run on iPhone 5, 6 and 6plus, and iPads. The .a files must include all the required binaries. How to compile such a library project and how to create the proper .a file for distribution? I am running Xcode 6.1 on OS X Yosemite (10.10).

Solution

You have to build a so called fat library for iOS projects. Find detailed instructions below. iOS applications use universal binary. That means one application can contain both of 32-bit and 64-bit code. If the actual device supports 64-bit mode, then your application will run in the faster 64-bit mode. 64-bit is becoming a requirement.

If you want to distribute your library, after the successful compilation, add all of the header files and other required assets to the distribution package. Unix convention for includes is an include folder for the header files, and a lib folder for the library files (.a). From the package create a single zip file for easy distribution.

How to create fat library?

1. Quit Xcode. You must run command line utilities to create a fat library. We prefer to use text files to run build commands (scripts). Old dogs create and name such a file as MAKEFILE.

2. For the first time, create a new text file and name it as MAKEFILE. You can use any other file name. Place it directly into the library project folder.

3. Open the MAKEFILE with a text editor and edit it:

XBUILD=/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild
PROJECT_ROOT=.
PROJECT=$(PROJECT_ROOT)/yourproject.xcodeproj

# The name of the target is generated by the Xcode
TARGET=your

# The name of the .a file is generated by the project, without the "lib" prefix or the ".a" suffix.
# This project will create libyour.a
LIB=your

all: libyourUniversal.a

libyouri386.a:
    $(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphonesimulator -configuration Release clean build
    -mv $(PROJECT_ROOT)/build/Release-iphonesimulator/lib$(LIB).a $@

libyourArmv7.a:
    $(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch armv7 -configuration Release clean build
    -mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(LIB).a $@

# We remove it from here. $(ARCHS_STANDARD) does not include armv7s. You can build armv7s binary though:
# libyourArmv7s.a:
#   $(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch armv7s -configuration Release clean build
#   -mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(LIB).a $@

libyourArm64.a:
    $(XBUILD) -project $(PROJECT) -target $(TARGET) -sdk iphoneos -arch arm64 -configuration Release clean build
    -mv $(PROJECT_ROOT)/build/Release-iphoneos/lib$(LIB).a $@

# Without armv7s:
libyourUniversal.a: libyouri386.a libyourArmv7.a libyourArm64.a
    lipo -create -output lib$(LIB)Universal.a $^

clean:
    -rm -f *.a *.dll
    -rm -rf build

Notes: When using the above sample please adjust it to your project and library name. Replace “yourproject.xcodeproj” and “your” with a real name. Armv7s is designed for A6 processor and supported from iPhone 5, 5c, 5S and iPad Air. These devices are 64-bit compatible. You do NOT have to build for armv7s to add support for the iPhone 5 family. Use 64 bit architecture.

4. Open Terminal, navigate to the project folder, and run: make -f MAKEFILE

5. After a minute or so, the build will be finished:

$ cd /Users/me/iPhone\ Projects/yourproject
$ make -f MAKEFILE
/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild -project ./yourproject.xcodeproj -target your -sdk iphonesimulator -configuration Release clean build
Build settings from command line:
    SDKROOT = iphonesimulator8.1
=== CLEAN TARGET your OF PROJECT your WITH CONFIGURATION Release ===
Check dependencies

... dozens of build messages ...

** BUILD SUCCEEDED **
mv ./build/Release-iphoneos/libyour.a libyourArm64.a
lipo -create -output libyourUniversal.a libyouri386.a libyouryArmv7.a libyourArm64.a
$

How to check a static library?

1. You have to open the Terminal and navigate to the your.a file.

2. Run: lipo -info your.a

For example:

$ cd /Users/me/iPhone\ Projects/Library
$ lipo -info libyourUniversal.a
Architectures in the fat file: libyourUniversal.a are: i386 x86_64 armv7 arm64
$