2

I have a workspace which has 2 projects: One is a Cocoa touch framework and the other is the app which uses the framework.I have added the framework in the embedded binaries section. When I run the app, it compiles the framework and the app and things are fine. However, I need the framework to compile for all architectures and not just the one it is currently being built for. I have searched for this and the most common solution is to add a run script to enable this functionality. However, every run script I have come across is different from one another, so I am confused what is the script that is ideal for this situation? Also, is it a good idea to create a fat binary for this purpose?

I am using the following script at the moment, that I have added to the build phase of the framework (taken from http://www.insert.io/frameworkios8xcode6/):

set -e
set +u
# Avoid recursively calling this script.
if [[ $SF_MASTER_SCRIPT_RUNNING ]]
then
exit 0
fi
set -u
export SF_MASTER_SCRIPT_RUNNING=1


# Constants
SF_TARGET_NAME=${PROJECT_NAME}
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

# Take build target
if [[ "$SDK_NAME" =~ ([A-Za-z]+) ]]
then
SF_SDK_PLATFORM=${BASH_REMATCH[1]}
else
echo "Could not find platform name from SDK_NAME: $SDK_NAME"
exit 1
fi

if [[ "$SF_SDK_PLATFORM" = "iphoneos" ]]
then
echo "Please choose iPhone simulator as the build target."
exit 1
fi

IPHONE_DEVICE_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos

# Build the other (non-simulator) platform
xcodebuild -project "${PROJECT_FILE_PATH}" -target "${TARGET_NAME}" -configuration "${CONFIGURATION}" -sdk iphoneos BUILD_DIR="${BUILD_DIR}" OBJROOT="${OBJROOT}" BUILD_ROOT="${BUILD_ROOT}" CONFIGURATION_BUILD_DIR="${IPHONE_DEVICE_BUILD_DIR}/arm64" SYMROOT="${SYMROOT}" ARCHS='arm64' VALID_ARCHS='arm64' $ACTION

xcodebuild -project "${PROJECT_FILE_PATH}" -target "${TARGET_NAME}" -configuration "${CONFIGURATION}" -sdk iphoneos BUILD_DIR="${BUILD_DIR}" OBJROOT="${OBJROOT}" BUILD_ROOT="${BUILD_ROOT}"  CONFIGURATION_BUILD_DIR="${IPHONE_DEVICE_BUILD_DIR}/armv7" SYMROOT="${SYMROOT}" ARCHS='armv7 armv7s' VALID_ARCHS='armv7 armv7s' $ACTION

# Copy the framework structure to the universal folder (clean it first)
rm -rf "${UNIVERSAL_OUTPUTFOLDER}"
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework"

# Smash them together to combine all architectures
lipo -create  "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/arm64/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/armv7/${PROJECT_NAME}.framework/${PROJECT_NAME}" -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}"

This script requires that the framework be built for iOS Simulator. After building the the .framework in the Products folder in my workspace shows that the framework is in iphoneos folder instead of the Universal folder. Should I drag the .framework from the Universal folder into the Products section in the worksapce?

Crazed'n'Dazed
  • 402
  • 1
  • 7
  • 20
  • In Xcode 12, here reports the following error: database is locked Possibly there are two concurrent builds running in the same filesystem location. – 慭慭流觞 Oct 16 '20 at 09:23

2 Answers2

0

I don't know about having the framework project and the app project in the same workspace, however you can see my answer here on how I did this. I didn't have to put the framework in embedded binaries. I only had to put in Linked Frameworks and Libraries. I just set up a build script that when I build for a Generic iOS Device, it builds a Fat Framework to my desktop. I can then run the -lipo info command to confirm this is actually a fat framework. From there I put the framework in my Linked Frameworks and Libraries in my app.

Community
  • 1
  • 1
arc4randall
  • 3,146
  • 3
  • 23
  • 39
0

What it worked for me was the following complete tutorial:

https://github.com/jverkoey/iOS-Framework

There you can see the benefits of using a Cocoa Touch static Library based Framework over a Static iOS Framework. It really is an open discuss, but I am only telling you my positive experience with it in a production environment.

The important command you have to care about is the lipo one. It's the one who will smash the binaries into a fat one. With that command you can easily check if the result contains the architectures you wanted or not. If not, check first this and then ensure you follow the instructions of the guide above.

Once you create the static library you can run the following command to check the architectures:

lipo -info YourLibrary.framework/YourLibrary

This solutions also allows you to include the framework as a dependent target to your project making your Framework development much easier. For that purpose check this chapter of the guide.

Community
  • 1
  • 1
GoRoS
  • 4,445
  • 2
  • 37
  • 57