Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xcode6 Creating Fat Static Library iOS Universal Framework

Since the upgrade to Xcode and iOS8, I've been having trouble building a fat static library. There are some pretty good instructions here and here but I think parts of the first instructions and all of the second instructions are dated. The first instructions say to use Static iOS Framework and the second instructions say to use Cocoa Touch Static Library. Prior to Xcode6, I would use the Static iOS Framework but now that they have renamed it to Cocoa Touch Framework I'm not sure.

So, for starters, which should I use to create a fat static library? Is it Cocoa Touch Framework? Or Cocoa Touch Static Library?

Cocoa Touch Framework

Cocoa Touch Static Library

Then I create a new Aggregate Target:

Aggregate Target

Then I create a Run Script:


Run Script


Here is the Run Script I am using (in its entirety):

# This script is based on Jacob Van Order's answer on apple dev forums 

https://devforums.apple.com/message/971277
# See also http://spin.atomicobject.com/2011/12/13/building-a-universal-framework-for-ios/ for the start


# To get this to work with a Xcode 6 Cocoa Touch Framework, create Framework
# Then create a new Aggregate Target. Throw this script into a Build Script Phrase on the Aggregate


######################
# Options
######################

REVEAL_ARCHIVE_IN_FINDER=true

FRAMEWORK_NAME="${PROJECT_NAME}"

SIMULATOR_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${FRAMEWORK_NAME}.framework"

DEVICE_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphoneos/${FRAMEWORK_NAME}.framework"

UNIVERSAL_LIBRARY_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal"

FRAMEWORK="${UNIVERSAL_LIBRARY_DIR}/${FRAMEWORK_NAME}.framework"


######################
# Build Frameworks
######################

xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphonesimulator -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator | echo

xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphoneos -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos | echo

#xcodebuild -target ${PROJECT_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" | echo

#xcodebuild -target ${PROJECT_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" | echo


######################
# Create directory for universal
######################

rm -rf "${UNIVERSAL_LIBRARY_DIR}"

mkdir "${UNIVERSAL_LIBRARY_DIR}"

mkdir "${FRAMEWORK}"


######################
# Copy files Framework
######################

cp -r "${DEVICE_LIBRARY_PATH}/." "${FRAMEWORK}"


######################
# Make fat universal binary
######################

lipo "${SIMULATOR_LIBRARY_PATH}/${FRAMEWORK_NAME}" "${DEVICE_LIBRARY_PATH}/${FRAMEWORK_NAME}" -create -output "${FRAMEWORK}/${FRAMEWORK_NAME}" | echo


######################
# On Release, copy the result to desktop folder
######################

if [ "${CONFIGURATION}" == "Release" ]; then
mkdir "${HOME}/Desktop/${FRAMEWORK_NAME}-${CONFIGURATION}-iphoneuniversal/"
cp -r "${FRAMEWORK}" "${HOME}/Desktop/${FRAMEWORK_NAME}-${CONFIGURATION}-iphoneuniversal/"
fi


######################
# If needed, open the Framework folder
######################

if [ ${REVEAL_ARCHIVE_IN_FINDER} = true ]; then
if [ "${CONFIGURATION}" == "Release" ]; then
open "${HOME}/Desktop/${FRAMEWORK_NAME}-${CONFIGURATION}-iphoneuniversal/"
else
open "${UNIVERSAL_LIBRARY_DIR}/"
fi
fi

But when I try to Build I receive this message:

fatal error: lipo: can't open input file: /Users/pdl/Library/Developer/Xcode/DerivedData/innerIDMobileLicense-blnxjfvoxnqfelftmzojgdwhvazk/Build/Products/Debug-iphonesimulator/innerIDMobileLicense.framework/innerIDMobileLicense (No such file or directory)

That's correct, the file isn't there! Notice in the first image below, there is a Unix Executable File IdAirOpenCv. Then look at the second image and notice that IdAirOpenCv isn't there.

This is what I am used to seeing prior to upgrading:

Old folder structure

This is what I have now:

New folder structure

According to the script, the Unix Executable File innerIDMobileLicense should be located inside all three of the framework folders at the same level as the Headers and Modules folders.

Does anybody have a clue what I am doing wrong?

like image 592
Patricia Avatar asked Nov 01 '22 13:11

Patricia


1 Answers

fatal error: lipo: can't open input file: /Users/pdl/Library/Developer/Xcode/DerivedData/innerIDMobileLicense-blnxjfvoxnqfelftmzojgdwhvazk/Build/Products/Debug-iphonesimulator/innerIDMobileLicense.framework/innerIDMobileLicense (No such file or directory)

This lipo error you got is most likely due to the containing directory does not exists.

The script is created when xcode does not have a framework project.

Lipo basically links two binary build for different architecture together to build a fat one.

So, for starters, which should I use to create a fat static library? Is it Cocoa Touch Framework? Or Cocoa Touch Static Library?

Either one will work. Lipo can link the binary inside the framework and a simple static library

What I did is to create a static library project, and a framework project. Set the static library target to be either device or simulator (using sdk iphoneos or iphonesimulator. Add the Universal Framework script into the framework project to build the static library with the other sdk and put the fat binary to the framework. Also copy needed headers to the framework project. The framework do not need to compile anything.

like image 79
guangyan wang Avatar answered Dec 01 '22 14:12

guangyan wang