Last active
March 2, 2020 17:14
-
-
Save joncardasis/ab6efec234ca46f15f9fe31adf6669e1 to your computer and use it in GitHub Desktop.
Build universal ios fat framework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# Builds the a framework for both the 64bit iOS architecture and | |
# a 64bit simulator architecture, combining the two into a single FAT framework. | |
# | |
set -e -o pipefail | |
print_available_options() { | |
printf "Usage: ./build_universal_ios_framework.sh -workspace <workspacepath> -target <targetname> -configuration <configurationname> -destination <destinationpath>\n\n" | |
printf "Options:\n" | |
printf " %-40s %s\n" "-workspace PATH" "the PATH to the workspace to build" | |
printf " %-40s %s\n" "-target NAME" "the target NAME to build" | |
printf " %-40s %s\n" "-configuration NAME" "the build configuration NAME for building all targets (ex. 'Debug', 'Release')" | |
printf " %-40s %s\n" "-destination PATH" "the destination of the universal framework described by PATH (ex. /path/to/MyFramework.framework)" | |
printf " %-40s %s\n" "-configuration-simulator NAME" "the build configuration NAME for building simulator target. Optional." | |
printf " %-40s %s\n" "-configuration-device NAME" "the build configuration NAME for building physical device target. Optional." | |
} | |
# Fills the options needed for the script to run. If the mandatory options are not given | |
# the script terminates with exit code 1. | |
# Parameters: 1. `$@` - all command arguments. | |
get_options() { | |
while test $# -gt 0; do | |
case "$1" in | |
-workspace ) | |
WORKSPACE_PATH=$2 | |
shift 2 | |
;; | |
-configuration ) | |
CONFIGURATION=$2 | |
shift 2 | |
;; | |
-configuration-simulator ) | |
CONFIGURATION_SIM=$2 | |
shift 2 | |
;; | |
-configuration-device ) | |
CONFIGURATION_IOS=$2 | |
shift 2 | |
;; | |
-target ) | |
TARGET_NAME=$2 | |
shift 2 | |
;; | |
-destination ) | |
FRAMEWORK_OUTPUT_PATH=$2 | |
shift 2 | |
;; | |
*) | |
echo "$1 is not a recognized flag." | |
exit 1; | |
;; | |
esac | |
done; | |
if [ -z "$CONFIGURATION_IOS" ] && [ -z "$CONFIGURATION_SIM" ]; then | |
CONFIGURATION_IOS="$CONFIGURATION" | |
CONFIGURATION_SIM="$CONFIGURATION" | |
elif [ -z "$CONFIGURATION_IOS" ] || [ -z "$CONFIGURATION_SIM" ]; then | |
echo "Both -configuration-simulator and -configuration-device must be specified when using separate configurations Use -configuration to use the same config for both targets." | |
exit 1 | |
fi | |
if [ -z "$WORKSPACE_PATH" ] || [ -z "$CONFIGURATION_IOS" ] || [ -z "$CONFIGURATION_SIM" ] || [ -z "$TARGET_NAME" ] || [ -z "$FRAMEWORK_OUTPUT_PATH" ]; then | |
echo "Not all parameters were given." | |
print_available_options | |
exit 1 | |
fi | |
} | |
# Get command line arguments | |
get_options $@ | |
# Workspace Setup | |
BUILD_DIR="$(mktemp -d)" | |
BUILD_ROOT="${BUILD_DIR}" | |
UNIVERSAL_OUTPUT_DIR="${BUILD_DIR}/${TARGET_NAME}-universal.framework" | |
mkdir -p "${UNIVERSAL_OUTPUT_DIR}" | |
# Build Simulator | |
xcodebuild \ | |
-workspace "${WORKSPACE_PATH}" \ | |
-scheme "${TARGET_NAME}" \ | |
-configuration ${CONFIGURATION_SIM} \ | |
-sdk iphonesimulator \ | |
-destination 'platform=iOS Simulator,name=iPhone X' \ | |
ONLY_ACTIVE_ARCH=NO ARCHS='x86_64' BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" ENABLE_BITCODE=YES SKIP_BUNDLING=YES \ | |
SKIP_BUNDLING=1 \ | |
clean build test | xcpretty | |
# Build Physical Device | |
xcodebuild \ | |
-workspace "${WORKSPACE_PATH}" \ | |
-scheme "${TARGET_NAME}" \ | |
-configuration "${CONFIGURATION_IOS}" \ | |
-sdk iphoneos \ | |
-destination='generic/platform=iOS' \ | |
ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" ENABLE_BITCODE=YES \ | |
clean build | xcpretty | |
# Copy the framework structure from the iphoneos build to universal folder | |
cp -R "${BUILD_DIR}/${CONFIGURATION_IOS}-iphoneos/${TARGET_NAME}.framework/" "${UNIVERSAL_OUTPUT_DIR}" | |
# Copy Swift modules from the iphonesimulator build to the universal folder | |
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION_SIM}-iphonesimulator/${TARGET_NAME}.framework/Modules/${TARGET_NAME}.swiftmodule/." | |
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then | |
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUT_DIR}/Modules/${TARGET_NAME}.swiftmodule" | |
fi | |
# Create universal binary from the simulator and physical device architecture builds | |
echo "Linking..." | |
lipo -create \ | |
"${BUILD_DIR}/${CONFIGURATION_SIM}-iphonesimulator/${TARGET_NAME}.framework/${TARGET_NAME}" \ | |
"${BUILD_DIR}/${CONFIGURATION_IOS}-iphoneos/${TARGET_NAME}.framework/${TARGET_NAME}" \ | |
-output "${UNIVERSAL_OUTPUT_DIR}/${TARGET_NAME}" | |
# Copy fat framework to desired output location | |
if [ -d "${FRAMEWORK_OUTPUT_PATH}" ]; then rm -Rf "${FRAMEWORK_OUTPUT_PATH}"; fi | |
mkdir -p $(dirname "${FRAMEWORK_OUTPUT_PATH}") | |
cp -R "${UNIVERSAL_OUTPUT_DIR}/." "${FRAMEWORK_OUTPUT_PATH}" | |
# Cleanup | |
rm -rf "${BUILD_DIR}" | |
echo "Finished creation of fat framework. Output: ${FRAMEWORK_OUTPUT_PATH}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment