Last active
March 28, 2021 00:56
-
-
Save CognitiveDisson/0ac4c8031ee60c0ec16de848e576ff42 to your computer and use it in GitHub Desktop.
Build universal frameworks
This file contains 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/sh | |
# Print all the commands in script before their execution | |
# export PS4='+ 6: ' | |
set -x | |
# Force the script to stop if any unhandled error occurs (i.e. an error not handled with `||`) | |
# set -e | |
# Force the script to stop if any uninitialized variable is used | |
set -u | |
# Force the script to bypass error result through all pipes if any pipe fails | |
set -o pipefail | |
# Get path to a folder containing the script | |
SCRIPT_ROOT=`cd "$(dirname "$0")" && pwd` | |
workspaceName="${SCRIPT_ROOT}/DependenciesBuilder.xcworkspace" | |
schemeName="Pods-DependenciesBuilder" | |
configurationName="Release" | |
inputPath="${SCRIPT_ROOT}/DerivedData.ignored" | |
outputPath="${SCRIPT_ROOT}/UniversalOutput.ignored" | |
podspecsPath="${SCRIPT_ROOT}/../" | |
# Navigate to script directory | |
cd "$(dirname "$0")" | |
# Prepare folders | |
rm -rf $inputPath | |
rm -rf $outputPath | |
# Update project pods | |
pod install --project-directory="${SCRIPT_ROOT}" || exit 1 | |
# Build frameworks for all architectures | |
xcodebuild \ | |
-workspace $workspaceName \ | |
-scheme $schemeName \ | |
-configuration $configurationName \ | |
-sdk iphoneos \ | |
-derivedDataPath $inputPath \ | |
build | xcpretty || exit 1 | |
xcodebuild \ | |
-workspace $workspaceName \ | |
-scheme $schemeName \ | |
-configuration $configurationName \ | |
-sdk iphonesimulator \ | |
-derivedDataPath $inputPath \ | |
build | xcpretty || exit 1 | |
frameworksCreated=0 | |
dsymsCreated=0 | |
if [ ! -d "${outputPath}" ]; then | |
echo "Create output folder" | |
mkdir "${outputPath}" | |
fi; | |
devicePath="${inputPath}/Build/Products/${configurationName}-iphoneos" | |
simulatorPath="${inputPath}/Build/Products/${configurationName}-iphonesimulator" | |
writePodspec() { | |
local name="${1:?}" | |
local module_name="${2:?}" | |
local version="${3:?}" | |
local podspecName="${name}.podspec" | |
local podspecPath="${podspecsPath}/${podspecName}" | |
if [ -e "${podspecPath}" ]; then | |
echo "Podspec ${podspecName} already exists" | |
return | |
fi | |
echo "podspecPath: $podspecPath" | |
{ | |
echo "Pod::Spec.new do |s|" | |
echo " s.name = '${name}'" | |
if [[ "${name}" != "${module_name}" ]]; then | |
echo " s.module_name = '${module_name}'" | |
fi | |
echo " s.version = '${version}'" | |
echo " s.summary = 'Prebuilded ${name}'" | |
echo " s.homepage = 'http://.../prebuilded-frameworks/${name}'" | |
echo " s.license = 'MIT'" | |
echo " s.author = { '$(git config --global user.name)' => '$(git config --global user.email)' }" | |
echo " s.source = { :git => 'ssh://.../prebuilded-frameworks.git', :branch => 'master' }" | |
echo " s.platform = :ios, '9.0'" | |
echo " s.ios.deployment_target = '9.0'" | |
echo " s.requires_arc = true" | |
echo " s.vendored_frameworks = '${name}/${module_name}.framework'" | |
echo "end" | |
} > "${podspecPath}" | |
} | |
for deviceFolder in $(find $devicePath -mindepth 1 -maxdepth 1); do | |
frameworkName=$(basename "${deviceFolder}") | |
echo "Process ${frameworkName} == ${schemeName}.framework" | |
tmpName=$(echo $frameworkName | tr '_' '-') | |
if [ "${tmpName}" == "${schemeName}.framework" ]; then | |
continue; | |
fi; | |
simulatorFolder="$simulatorPath/$frameworkName" | |
deviceFrameworkPath=$(find $deviceFolder -mindepth 1 -maxdepth 1 | grep '.*\.framework$') | |
simulatorFrameworkPath=$(find $simulatorFolder -mindepth 1 -maxdepth 1 | grep '.*\.framework$') | |
if [ ! -d "$deviceFrameworkPath" ]; then continue; fi; | |
echo "Process $(tput bold)$frameworkName$(tput sgr0)" | |
if [ ! -d "$simulatorFrameworkPath" ]; then | |
echo " Could not find simulator framework" | |
continue | |
fi; | |
binaryName="$(basename $deviceFrameworkPath)" | |
binaryName="${binaryName%.*}" | |
deviceBinaryPath="$deviceFrameworkPath/$binaryName" | |
simulatorBinaryPath="$simulatorFrameworkPath/$binaryName" | |
if [ ! -f "$deviceBinaryPath" ]; then | |
echo " Could not find binary file for device" | |
continue | |
fi; | |
if [ ! -f "$simulatorBinaryPath" ]; then | |
echo " Could not find binary file for simulator" | |
continue | |
fi; | |
echo " Copy device framework" | |
cp -r "${deviceFrameworkPath}" "${outputPath}" | |
frameworkFileName="$(basename $deviceFrameworkPath)" | |
universalBinaryPath="${outputPath}/$frameworkFileName/$binaryName" | |
similatorSwiftModulesPath="${simulatorFrameworkPath}/Modules/$frameworkName.swiftmodule" | |
universalSwiftModulesPath="${outputPath}/$frameworkFileName/Modules/" | |
if [ -d "$similatorSwiftModulesPath" ]; then | |
echo " Copy simulator swiftModules" | |
cp -r "$similatorSwiftModulesPath" "$universalSwiftModulesPath" | |
fi; | |
echo " Merge framework architectures" | |
lipo -create $deviceBinaryPath $simulatorBinaryPath -o $universalBinaryPath | |
echo "success lipo" | |
let "frameworksCreated++" | |
deviceDsymPath=$(find $deviceFolder -mindepth 1 -maxdepth 1 | grep '.*\.framework.dSYM$') | |
simulatorDsymPath=$(find $simulatorFolder -mindepth 1 -maxdepth 1 | grep '.*\.framework.dSYM$') | |
echo "success find dsym" | |
if [ ! -d "$deviceDsymPath" ]; then | |
echo " Could not find dSYM for device" | |
continue | |
fi; | |
if [ ! -d "$simulatorDsymPath" ]; then | |
echo " Could not find dSYM for simulator" | |
continue | |
fi; | |
echo " Copy device dSYM" | |
cp -r "${deviceDsymPath}" "${outputPath}" | |
deviceDwafrPath="$deviceDsymPath/Contents/Resources/DWARF/$binaryName" | |
simulatorDwafrPath="$simulatorDsymPath/Contents/Resources/DWARF/$binaryName" | |
universalDwarfPath="${outputPath}/$frameworkFileName.dSYM/Contents/Resources/DWARF/$binaryName" | |
echo " Merge dSYM architectures" | |
lipo -create $deviceDwafrPath $simulatorDwafrPath -o $universalDwarfPath | |
let "dsymsCreated++" | |
frameworkModuleName="${frameworkFileName%.*}" | |
frameworkName=$(echo $frameworkModuleName | tr '_' '-') | |
version=$(cat Podfile.lock | grep -e "-[[:space:]]${frameworkName}.*[[:space:]]([0-9]\+" | sed 's#.*(##' | sed 's#).*##' | head -1) | |
frameworkPath="${outputPath}/${frameworkFileName}" | |
dwarfPath="${outputPath}/${frameworkFileName}.dSYM" | |
frameworkDirectory="${podspecsPath}/${frameworkName}" | |
mkdir -p $frameworkDirectory | |
frameworkDestination="${frameworkDirectory}/${frameworkModuleName}.framework" | |
dwarfDestination="${frameworkDirectory}/${frameworkModuleName}.framework.dSYM" | |
rm -rf $frameworkDestination | |
rm -rf $dwarfDestination | |
mv $frameworkPath $frameworkDestination | |
mv $dwarfPath $dwarfDestination | |
writePodspec "${frameworkName}" "${frameworkModuleName}" "${version}" | |
done | |
# Clean folders | |
rm -rf $inputPath | |
rm -rf $outputPath | |
echo "$(tput bold)Done! $frameworksCreated frameworks created with $dsymsCreated dSYMs $(tput sgr0)" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi @daukabase. In this code a vendored framework is the framework that we are trying to pre-build, not dependencies. As you can see from the code, there is nothing about dependencies there. All dependency linking flags will already be set in the binary after the build. You just need to include all dependencies in the final build.
Example: We are trying to pre-build the RxCocoa framework. The podspec file looks like this:
If we run this script, we will get another podspec for the prebuilded framework.
What we need to do is to make it work eventually, it also runs this script for other dependencies - RxRelay & RxSwift, and integrate them to Podfile.
The only problem is that you need to specify all the transitive dependencies for the framework you are trying to pre-build in order to specify the path to them.