【问题标题】:Run script for universal framework on Xcode 10在 Xcode 10 上运行通用框架的脚本
【发布时间】:2019-06-23 10:23:17
【问题描述】:

我是 Xcode 9.x,我使用了以下脚本,它运行良好:

######################
# Options
######################

REVEAL_ARCHIVE_IN_FINDER=false

FRAMEWORK_NAME="${PROJECT_NAME}"

SIMULATOR_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${FRAMEWORK_NAME}.framework"

DEVICE_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphoneos/${FRAMEWORK_NAME}.framework"

UNIVERSAL_LIBRARY_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal"

FRAMEWORK="${UNIVERSAL_LIBRARY_DIR}/${FRAMEWORK_NAME}.framework"


######################
# Build Frameworks
######################

xcodebuild -project "${PROJECT_FILE_PATH}" -target "${TARGET_NAME}"
ONLY_ACTIVE_ARCH=NO -configuration "${CONFIGURATION}" -sdk iphonesimulator
BUILD_DIR="${BUILD_DIR}" OBJROOT="${OBJROOT}" BUILD_ROOT="${BUILD_ROOT}"
CONFIGURATION_BUILD_DIR="${IPHONE_SIMULATOR_BUILD_DIR}" SYMROOT="${SYMROOT}"
ARCHS="i386 x86_64" ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode" $ACTION 2>&1

xcodebuild -project "${PROJECT_FILE_PATH}" -target "${TARGET_NAME}"
ONLY_ACTIVE_ARCH=NO -configuration "${CONFIGURATION}" -sdk iphoneos
BUILD_DIR="${BUILD_DIR}" OBJROOT="${OBJROOT}" BUILD_ROOT="${BUILD_ROOT}"
CONFIGURATION_BUILD_DIR="${IPHONE_DEVICE_BUILD_DIR}" SYMROOT="${SYMROOT}"
ARCHS="armv7 armv7s arm64" ENABLE_BITCODE=YES OTHER_CFLAGS="-fembed-bitcode" $ACTION 2>&1

######################
# Create directory for universal
######################

rm -rf "${UNIVERSAL_LIBRARY_DIR}"

mkdir "${UNIVERSAL_LIBRARY_DIR}"

mkdir "${FRAMEWORK}"


######################
# Copy files Framework
######################

cp -r "${DEVICE_LIBRARY_PATH}/." "${FRAMEWORK}"


######################
# Make an universal binary
######################

lipo "${SIMULATOR_LIBRARY_PATH}/${FRAMEWORK_NAME}" "${DEVICE_LIBRARY_PATH}/${FRAMEWORK_NAME}" -create -output "${FRAMEWORK}/${FRAMEWORK_NAME}" | echo

# For Swift framework, Swiftmodule needs to be copied in the universal framework
if [ -d "${SIMULATOR_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/" ]; then
cp -f ${SIMULATOR_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/* "${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/" | echo
                                                                      fi

                                                                      if [ -d "${DEVICE_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/" ]; then
                                                                      cp -f ${DEVICE_LIBRARY_PATH}/Modules/${FRAMEWORK_NAME}.swiftmodule/* "${FRAMEWORK}/Modules/${FRAMEWORK_NAME}.swiftmodule/" | echo
                                                                      fi

                                                                      ######################
                                                                      # On Release, copy the result to release directory
                                                                      ######################
                                                                      OUTPUT_DIR="${PROJECT_DIR}/Output/${FRAMEWORK_NAME}-${CONFIGURATION}-iphoneuniversal/"

                                                                      rm -rf "$OUTPUT_DIR"
                                                                      mkdir -p "$OUTPUT_DIR"

                                                                      cp -r "${FRAMEWORK}" "$OUTPUT_DIR"

                                                                      if [ ${REVEAL_ARCHIVE_IN_FINDER} = true ]; then
                                                                      open "${OUTPUT_DIR}/"
                                                                      fi

这不适用于 Xcode 10。后来我看到脚本中需要进行一些修改。所以我按照this的回答设置了脚本。但设置此脚本后,当我尝试构建通用框架时,Xcode 挂在 Building script 1 of 1。
我一直在尝试寻找正确的解决方案,但每次都失败了。
Xcode 10 上的通用框架(涵盖所有架构)的正确运行脚本是什么?

【问题讨论】:

  • 嗨 Nitish,您可以使用此工具解决未来可能出现的问题:github.com/gurhub/surmagicBest。
  • 太棒了!非常感谢@mgyky

标签: ios xcode xcode10 ios-frameworks ios-universal-framework


【解决方案1】:

打开终端,导航到项目的根目录将 YourUniversalFramework 替换为您的项目名称和方案名称(如果需要),运行命令成功后会生成universal文件夹inside build

通用文件夹中的框架现在可以被设备和模拟器使用了!

注意:更改后将整个脚本粘贴到终端并运行

.xcodeproj 项目的命令/脚本

mkdir build
    ;
    xcodebuild clean build \
      -project YourUniversalFramework.xcodeproj \
      -scheme YourUniversalFramework \
      -configuration Release \
      -sdk iphoneos \
      -derivedDataPath derived_data \
      BUILD_LIBRARY_FOR_DISTRIBUTION=YES 
    ;
    mkdir build/devices
    ;
    cp -r derived_data/Build/Products/Release-iphoneos/YourUniversalFramework.framework build/devices
    ;
    xcodebuild clean build \
      -project YourUniversalFramework.xcodeproj \
      -scheme YourUniversalFramework \
      -configuration Release \
      -sdk iphonesimulator \
      -derivedDataPath derived_data \
      BUILD_LIBRARY_FOR_DISTRIBUTION=YES
    ;
    mkdir build/simulator
    ;
    cp -r derived_data/Build/Products/Release-iphonesimulator/ build/simulator/
    ;
    mkdir build/universal
    ;
    cp -r build/devices/YourUniversalFramework.framework build/universal/
    ;
    lipo -create \
      build/simulator/YourUniversalFramework.framework/YourUniversalFramework \
      build/devices/YourUniversalFramework.framework/YourUniversalFramework \
      -output build/universal/YourUniversalFramework.framework/YourUniversalFramework
    ;
    cp -r \
    build/simulator/YourUniversalFramework.framework/Modules/YourUniversalFramework.swiftmodule/* \
    build/universal/YourUniversalFramework.framework/Modules/YourUniversalFramework.swiftmodule/YourUniversalFramework

.xcworkspace 项目的命令/脚本

mkdir build
    ;
    xcodebuild clean build \
      -workspace YourUniversalFramework.xcworkspace \
      -scheme YourUniversalFramework \
      -configuration Release \
      -sdk iphoneos \
      -derivedDataPath derived_data \
      BUILD_LIBRARY_FOR_DISTRIBUTION=YES 
    ;
    mkdir build/devices
    ;
    cp -r derived_data/Build/Products/Release-iphoneos/YourUniversalFramework.framework build/devices
    ;
    xcodebuild clean build \
      -workspace YourUniversalFramework.xcworkspace \
      -scheme YourUniversalFramework \
      -configuration Release \
      -sdk iphonesimulator \
      -derivedDataPath derived_data \
      BUILD_LIBRARY_FOR_DISTRIBUTION=YES
    ;
    mkdir build/simulator
    ;
    cp -r derived_data/Build/Products/Release-iphonesimulator/ build/simulator/
    ;
    mkdir build/universal
    ;
    cp -r build/devices/YourUniversalFramework.framework build/universal/
    ;
    lipo -create \
      build/simulator/YourUniversalFramework.framework/YourUniversalFramework \
      build/devices/YourUniversalFramework.framework/YourUniversalFramework \
      -output build/universal/YourUniversalFramework.framework/YourUniversalFramework
    ;
    cp -r \
    build/simulator/YourUniversalFramework.framework/Modules/YourUniversalFramework.swiftmodule/* \
    build/universal/YourUniversalFramework.framework/Modules/YourUniversalFramework.swiftmodule/YourUniversalFramework

【讨论】:

    【解决方案2】:
    echo "project"
    #open "${PROJECT_DIR}"
    if [ "true" == ${ALREADYINVOKED:-false} ]
    then
    echo "RECURSION: Detected, stopping"
    else
    export ALREADYINVOKED="true"
    
    UNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-iosuniversal
    
    # make sure the output directory exists
    mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"
    
    # Step 1. Build Device and Simulator versions
    echo "iphone"
    xcodebuild -target "${TARGET_NAME}" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -sdk iphoneos  BUILD_DIR="${BUILD_DIR}" BUILD_ROOT="${BUILD_ROOT}" clean build
    echo "iphonesim"
    xcodebuild -target "${TARGET_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
    echo "universal"
    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
    echo "iphone simulator path"
    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
    echo "lipo create"
    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}"
    
    echo "end"
    fi
    

    首先为模拟器和设备生成单独的构建 打开您的产品文件夹时,您将找到两者的单独构建 然后在你的项目中使用这个 Run 脚本

    生成脚本后,您在同一产品文件夹中找到文件夹 IOS-Universal

    对我来说工作正常。

    以下截图image

    【讨论】:

      【解决方案3】:

      -UseModernBuildSystem=NO 添加到 xcodebuild 命令应该可以工作。

      xcodebuild -workspace ${PROJECT_NAME}.xcworkspace -scheme ${PROJECT_NAME} -sdk iphonesimulator -configuration ${CONFIGURATION} -UseModernBuildSystem=NO clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphonesimulator 2>&1
      
      xcodebuild -workspace ${PROJECT_NAME}.xcworkspace -scheme ${PROJECT_NAME} -sdk iphoneos -configuration ${CONFIGURATION} -UseModernBuildSystem=NO clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneos 2>&1
      

      它应该可以解决您的问题。

      这是我目前正在使用的整个脚本,它成功地使用 Xcode 10 构建了通用框架。Link to gist

      目前,正在努力利用最新的构建系统来构建通用框架。很快就会更新答案。

      【讨论】:

      • 我想为幸福而哭泣;(它工作得很好。非常感谢 Dhruv
      • 干杯。 :) 编码快乐!
      • @Dhruv,网址 404
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-11
      • 1970-01-01
      • 2011-04-22
      • 2018-04-15
      • 1970-01-01
      • 2020-05-23
      • 2012-02-21
      相关资源
      最近更新 更多