Creating an Universal Library for iOS

Unofficial Content

When including a framework in your application (External Object or User control for SD), make sure the framework was build as a Universal Library for iOS.

A universal library can be defined as a framework that contains a binary which has been built for a number of architectures (armv6, armv7, i386) and can be statically linked against. This way you can compile and execute your application against the iPhone|iPad emulator or devices.

To create a universal library, a new aggregate target must be added in your xCode library project. It will wrap a number of script executables and copy file tasks in a specified order to generate a .a file.

Create Aggregate Target

Open the xCode project associated to your library and add a new Target (New Target | select "Other" under iOS | "Aggregate") and give it a name, for example "Build Universal Library".

Check the "Build Settings" section, make sure the PRODUCT_NAME matches your library name, for example "MyLibrary".

On the aggregate target, we need to add a new "Build Phases". Select "Build Phases" | Click "Add Build Phase" | Select "Add Run Script" and paste the following script:

LIB_TARGET_NAME="MyLibraryName|MyUserControlName"

if [ "${ACTION}" = "clean" ]
then
echo "Cleaning Libraries..."
cd "${PROJECT_DIR}"
xcodebuild -target "$LIB_TARGET_NAME" -configuration ${CONFIGURATION} -sdk iphoneos clean
xcodebuild -target "$LIB_TARGET_NAME" -configuration ${CONFIGURATION} -sdk iphonesimulator clean
fi

if [ "${ACTION}" = "build" ]
then
echo "Building Libraries"
cd "${PROJECT_DIR}"
xcodebuild -target "$LIB_TARGET_NAME" -configuration ${CONFIGURATION} -sdk iphoneos
xcodebuild -target "$LIB_TARGET_NAME" -configuration ${CONFIGURATION} -sdk iphonesimulator

# Check that this is what your static libraries are called
ARM_FILES="${PROJECT_DIR}/build/${CONFIGURATION}-iphoneos/lib${LIB_TARGET_NAME}.a"
I386_FILES="${PROJECT_DIR}/build/${CONFIGURATION}-iphonesimulator/lib${LIB_TARGET_NAME}.a"

mkdir -p "${PROJECT_DIR}/build/Universal"

echo "Creating library..."
lipo -create "$ARM_FILES" "$I386_FILES" -o "${PROJECT_DIR}/build/Universal/lib${PRODUCT_NAME}.a"
fi

make sure the

LIB_TARGET_NAME="MyLibrary"

variable references your library name or User Control for Smart Devices name.

The script does the following:

  • builds the library for iphoneos and iphonesimulator.
  • creates a new folder "Universal" to locate the merged .a file.
  • merges the static libraries built for the various architectures into a fat binary using the lipo tool.

Once the universal .a file is created, move the appropriate files into place. This means: copy your universal library for example MyLibrary.a to the UserControls folder and the header file into the Classes folder under the iOS folder.

You can verify that the binary was built for the correct architectures using lipo:

lipo -info /Users/GeneXus/Projects/MyLibrary/build/Universal/libMyLibrary.a
Architectures in the fat file: /Users/GeneXus/Projects/MyLibrary/build/Universal/libMyLibrary.a are: armv7 armv6 i386

See Also

The following article details how to build a Universal Framework for iOS.