Skip to content

Instantly share code, notes, and snippets.

@cromandini
Forked from cconway25/gist:7ff167c6f98da33c5352
Last active November 9, 2024 08:56
Show Gist options
  • Save cromandini/1a9c4aeab27ca84f5d79 to your computer and use it in GitHub Desktop.
Save cromandini/1a9c4aeab27ca84f5d79 to your computer and use it in GitHub Desktop.
This run script will build the iphoneos and iphonesimulator schemes and then combine them into a single framework using the lipo tool (including all the Swift module architectures).
#!/bin/sh
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
# Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"
# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi
# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"
# Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"
# Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"
@kashiftriffort
Copy link

kashiftriffort commented Mar 29, 2018

@i have created universal framework and it worked sucessfully with Target App. However if I want to add any external framework like Firebase or any other insider universal framework, how can we achieve that. Below is the script which is used for creating universal framework.

#!/bin/sh

UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

# Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"

# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi

# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"

# Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"

# Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"

@fabiosoft
Copy link

Tested with Xcode 10?

@SwenVanZanten
Copy link

Yes, just used it 👍
Thanks y'all 🥇

@aboud-masoud
Copy link

/core/build` because it was not created by the build system and it is not a subfolder of derived data

Please can any one help me when I try to run the script I got this error

@Atsumi3
Copy link

Atsumi3 commented Nov 7, 2018

nicework 👍

@shiqp
Copy link

shiqp commented Dec 10, 2018

Thanks in advance for my question.
What about the dsym file. Both simulator and iphoneos will generate dsym files. Should I use lipo to combine them as well?

Any solution for this problem?

@wellbranding
Copy link

not working with cocoa pods dependencies. here is more information:
https://www.reddit.com/r/swift/comments/admgcu/compiled_framework_provides_bitcode_error_when/

@jofvr
Copy link

jofvr commented May 14, 2019

Hello, i have import this script in my framework by follow this article. Archive work fine, it open the folder but when i copy the generated framework into my project, i have an error :
Could not find module '' for architecture 'x86_64'; found: arm64, arm, armv7
It work fine on device... Does i have make somethings wrong ?

@hackiftekhar
Copy link

The PROJECT_NAME should be replace by TARGET_NAME

@jofvr
Copy link

jofvr commented May 21, 2019

Thanks for answer. I have the same error when build my project with framework :

Could not find module '' for architecture 'x86_64'; found: arm64, arm, armv7

@fonixland
Copy link

There is a little more info on how this unsupported (according to Apple) feature broke in Xcode 10. Quinn suggests making a feature request so that Apple will hopefully officially support it in the future. There is also a similar script which purports to work with Xcode 10, but I have not personally tested it yet, so YMMV.

https://forums.developer.apple.com/thread/109583

Copy link

ghost commented Jun 27, 2019

Thanks for answer. I have the same error when build my project with framework :

Could not find module '' for architecture 'x86_64'; found: arm64, arm, armv7

Is any solution for this issue

@Linezek
Copy link

Linezek commented Oct 22, 2019

@i have created universal framework and it worked sucessfully with Target App. However if I want to add any external framework like Firebase or any other insider universal framework, how can we achieve that. Below is the script which is used for creating universal framework.

#!/bin/sh

UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal

# make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

# Step 1. Build Device and Simulator versions
xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
xcodebuild -target "${PROJECT_NAME}" -configuration ${CONFIGURATION} -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build

# Step 2. Copy the framework structure (from iphoneos build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"

# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi

# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"

# Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${PROJECT_DIR}"

# Step 6. Convenience step to open the project's directory in Finder
open "${PROJECT_DIR}"

Have you found a solution to include Firebase in your universal framework?

@simform-solutions
Copy link

simform-solutions commented Nov 18, 2019

#!/bin/sh
UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal
OUTPUT_FOLDER=${PROJECT_DIR}

make sure the output directory exists
mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

Step 1. Build Device and Simulator versions. This also includes the full bitcode generation of the framework
xcodebuild BITCODE_GENERATION_MODE=bitcode OTHER_CFLAGS="-fembed-bitcode" -workspace ${PROJECT_NAME}.xcworkspace -scheme ${PROJECT_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" -UseModernBuildSystem=NO clean build

xcodebuild BITCODE_GENERATION_MODE=bitcode OTHER_CFLAGS="-fembed-bitcode" -workspace ${PROJECT_NAME}.xcworkspace -scheme ${PROJECT_NAME} ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphonesimulator BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" -UseModernBuildSystem=NO clean build

Step 2. Copy the framework structure (from iPhones build) to the universal folder
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"

Step 3. Copy Swift modules (from iphonesimulator build) to the copied framework directory
cp -R "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/." "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"

Step 4. Create a universal binary file using lipo and place the combined executable in the copied framework directory
lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}"

Step 5. Convenience step to copy the framework to the project's directory
cp -R "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework" "${OUTPUT_FOLDER}"
Step 6. Convenience step to open the project's directory in Finder
open "${OUTPUT_FOLDER}"

I'm running this script to build a framework with cocoapods earlier in Xcode 10.3 it's working fine, But in new Xcode 11.2.1, this script is not working. can you please find me a workaround.

error ->

error: no such file or directory: '/Users/username/Documents/GitHub/sdkname/GenaratefremeWork/Pods/@/Users/username/Library/Developer/Xcode/DerivedData/SDK-ddyylnfmgscnezeppcqlekfbplzy/Build/Intermediates.noindex/SDK.build/Debug-iphoneos/SDK.build/Objects-normal/arm64/SDK.SwiftFileList'
Command /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc failed with exit code 1

@IkeStarnes
Copy link

This is great, but how do you avoid running steps 2,3,4,5... if step #1 doesn't actually rebuild the framework?
In other words, if no source code changes between builds, how do you avoid the copy and lipo steps?

@KarenShaham
Copy link

Hi! great work! I'm having a problem with resources included in my SDK.
It seems the script creates another exe file inside the bundle.
Do you have any ideas how to handle it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment