Skip to content

Instantly share code, notes, and snippets.

@CognitiveDisson
Last active March 28, 2021 00:56
Show Gist options
  • Select an option

  • Save CognitiveDisson/0ac4c8031ee60c0ec16de848e576ff42 to your computer and use it in GitHub Desktop.

Select an option

Save CognitiveDisson/0ac4c8031ee60c0ec16de848e576ff42 to your computer and use it in GitHub Desktop.

Revisions

  1. CognitiveDisson revised this gist Jun 23, 2019. No changes.
  2. CognitiveDisson revised this gist Jun 23, 2019. No changes.
  3. CognitiveDisson created this gist Jun 23, 2019.
    208 changes: 208 additions & 0 deletions build-universal-frameworks.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,208 @@
    #!/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)"