iOS静态库项目无法构建XCFramework问题求助
静态库构建XCFramework失败问题分析与解决
问题背景
我是iOS开发新手,此前在Xcode 10及更早版本中可从静态库构建.framework文件,现在尝试构建支持iOS设备与M1架构iOS模拟器的XCFramework,但始终无法成功。查阅大量博客及Stack Overflow解答仍未找到解决办法。
旧构建脚本(生成.framework)
set -e # If we're already inside this script then abort if [ -n "$RW_MULTIPLATFORM_BUILD_IN_PROGRESS" ]; then exit 0 fi export RW_MULTIPLATFORM_BUILD_IN_PROGRESS=1 RW_FRAMEWORK_NAME=${PROJECT_NAME} RW_INPUT_STATIC_LIB="lib${PROJECT_NAME}.a" RW_FRAMEWORK_LOCATION="${BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework" function build_static_library { # Will rebuild the static library as specified # build_static_library sdk xcrun xcodebuild -project "${PROJECT_FILE_PATH}" \ -target "${TARGET_NAME}" \ -configuration "${CONFIGURATION}" \ -sdk "${1}" \ ONLY_ACTIVE_ARCH=NO \ BUILD_DIR="${BUILD_DIR}" \ OBJROOT="${OBJROOT}/DependentBuilds" \ BUILD_ROOT="${BUILD_ROOT}" \ SYMROOT="${SYMROOT}" $ACTION } function make_fat_library { # Will smash 2 static libs together # make_fat_library in1 in2 out xcrun lipo -create "${1}" "${2}" -output "${3}" } # 1 - Extract the platform (iphoneos/iphonesimulator) from the SDK name if [[ "$SDK_NAME" =~ ([A-Za-z]+) ]]; then RW_SDK_PLATFORM=${BASH_REMATCH[1]} else echo "Could not find platform name from SDK_NAME: $SDK_NAME" exit 1 fi # 2 - Extract the version from the SDK if [[ "$SDK_NAME" =~ ([0-9]+.*$) ]]; then RW_SDK_VERSION=${BASH_REMATCH[1]} else echo "Could not find sdk version from SDK_NAME: $SDK_NAME" exit 1 fi # 3 - Determine the other platform if [ "$RW_SDK_PLATFORM" == "iphoneos" ]; then RW_OTHER_PLATFORM=iphonesimulator else RW_OTHER_PLATFORM=iphoneos fi # 4 - Find the build directory if [[ "$BUILT_PRODUCTS_DIR" =~ (.*)$RW_SDK_PLATFORM$ ]]; then RW_OTHER_BUILT_PRODUCTS_DIR="${BASH_REMATCH[1]}${RW_OTHER_PLATFORM}" else echo "Could not find other platform build directory." exit 1 fi # Build the other platform. build_static_library "${RW_OTHER_PLATFORM}${RW_SDK_VERSION}" # If we're currently building for iphonesimulator, then need to rebuild # to ensure that we get both i386 and x86_64 if [ "$RW_SDK_PLATFORM" == "iphonesimulator" ]; then build_static_library "${SDK_NAME}" fi # Join the 2 static libs into 1 and push into the .framework make_fat_library "${BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}" \ "${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_INPUT_STATIC_LIB}" \ "${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}" # Ensure that the framework is present in both platform's build directories cp -a "${RW_FRAMEWORK_LOCATION}/Versions/A/${RW_FRAMEWORK_NAME}" \ "${RW_OTHER_BUILT_PRODUCTS_DIR}/${RW_FRAMEWORK_NAME}.framework/Versions/A/${RW_FRAMEWORK_NAME}" # Copy the framework to the user's desktop ditto "${RW_FRAMEWORK_LOCATION}" "${HOME}/Desktop/${RW_FRAMEWORK_NAME}.framework"
新XCFramework构建脚本
SIMULATOR_ARCHIVE_PATH="${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphonesimulator.xcarchive" DEVICE_ARCHIVE_PATH="${BUILD_DIR}/${CONFIGURATION}/${FRAMEWORK_NAME}-iphoneos.xcarchive" echo "Simulator Path:$SIMULATOR_ARCHIVE_PATH" echo "Device Archive Path: $DEVICE_ARCHIVE_PATH" echo "Build DIR: $BUILD_DIR" echo "Configuration Path: $CONFIGURATION" OUTPUT_DIR="./Products/" # Simulator xcarchive (arm64 + x86_64) xcodebuild archive \ ONLY_ACTIVE_ARCH=NO \ -scheme ${SCHEME_NAME} \ -project "${SCHEME_NAME}.xcodeproj" \ -archivePath ${SIMULATOR_ARCHIVE_PATH} \ -sdk iphonesimulator \ BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ SKIP_INSTALL=NO # Device xcarchive (arm64) xcodebuild archive \ -scheme ${SCHEME_NAME} \ -project "${SCHEME_NAME}.xcodeproj" \ -archivePath ${DEVICE_ARCHIVE_PATH} \ -sdk iphoneos \ BUILD_LIBRARY_FOR_DISTRIBUTION=YES \ SKIP_INSTALL=NO # Clean-up any existing instance of this xcframework from the Products directory rm -rf "${OUTPUT_DIR}${SCHEME_NAME}.xcframework" # Create final xcframework xcodebuild -create-xcframework \ -framework ${DEVICE_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \ -framework ${SIMULATOR_ARCHIVE_PATH}/Products/Library/Frameworks/${FRAMEWORK_NAME}.framework \ -output ${BUILD_DIR}/${FRAMEWORK_NAME}.xcframework
报错信息
2023-11-20 23:44:06.736 xcodebuild[8267:239962] Writing error result bundle to /var/folders/ps/r75vk_f95tl2wh16jj2syv7c0000gr/T/ResultBundle_2023-20-11_23-44-0006.xcresult xcodebuild: error: Unknown build action '.xcodeproj'. error: the path does not point to a valid framework: /Users/coder/Library/Developer/Xcode/DerivedData/CoderSDK-cjavkiibuxlwhgftpsbjmlkavwpx/Build/Products/Debug/-iphoneos.xcarchive/Products/Library/Frameworks/.framework
问题分析与解决
1. 环境变量未正确赋值
报错中的路径/Debug/-iphoneos.xcarchive和Unknown build action '.xcodeproj'错误,都是因为脚本中的${SCHEME_NAME}和${FRAMEWORK_NAME}变量为空导致:
- 当
${SCHEME_NAME}为空时,-project "${SCHEME_NAME}.xcodeproj"会变成-project .xcodeproj,xcodebuild会把.xcodeproj误认为是build action,触发错误。 FRAMEWORK_NAME为空会导致归档路径出现空段,生成的归档自然找不到.framework文件。
解决方法:
在脚本开头手动赋值这两个变量(如果项目名称和scheme、framework名称一致,也可以用${PROJECT_NAME}替代):
# 替换成你的项目实际名称 SCHEME_NAME="CoderSDK" FRAMEWORK_NAME="CoderSDK"
2. 静态库归档不会生成.framework
你的项目是静态库,直接用xcodebuild archive生成的归档文件中,默认不会包含.framework(该逻辑仅针对动态framework),所以用-framework参数创建XCFramework会找不到文件。
正确脚本(针对静态库生成XCFramework):
直接构建不同平台的静态库,然后用-library参数结合头文件路径创建XCFramework:
# 手动设置项目信息 SCHEME_NAME="CoderSDK" FRAMEWORK_NAME="CoderSDK" CONFIGURATION="Debug" # 替换成你的头文件目录,比如项目根目录下的Headers文件夹 HEADER_DIR="${PROJECT_DIR}/Headers" # 构建模拟器静态库(支持x86_64 + arm64) SIMULATOR_BUILD_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" xcodebuild build \ -scheme ${SCHEME_NAME} \ -project "${SCHEME_NAME}.xcodeproj" \ -sdk iphonesimulator \ CONFIGURATION_BUILD_DIR=${SIMULATOR_BUILD_DIR} \ ONLY_ACTIVE_ARCH=NO \ BUILD_LIBRARY_FOR_DISTRIBUTION=YES # 构建设备静态库(arm64) DEVICE_BUILD_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneos" xcodebuild build \ -scheme ${SCHEME_NAME} \ -project "${SCHEME_NAME}.xcodeproj" \ -sdk iphoneos \ CONFIGURATION_BUILD_DIR=${DEVICE_BUILD_DIR} \ ONLY_ACTIVE_ARCH=NO \ BUILD_LIBRARY_FOR_DISTRIBUTION=YES # 清理旧的XCFramework rm -rf "${BUILD_DIR}/${FRAMEWORK_NAME}.xcframework" # 创建XCFramework xcodebuild -create-xcframework \ -library "${DEVICE_BUILD_DIR}/lib${FRAMEWORK_NAME}.a" \ -headers "${HEADER_DIR}" \ -library "${SIMULATOR_BUILD_DIR}/lib${FRAMEWORK_NAME}.a" \ -headers "${HEADER_DIR}" \ -output "${BUILD_DIR}/${FRAMEWORK_NAME}.xcframework"
3. 关键参数说明
BUILD_LIBRARY_FOR_DISTRIBUTION=YES:必须添加,确保生成XCFramework所需的模块元数据(比如.modulemap或.swiftmodule),否则其他项目引入XCFramework会无法识别模块。ONLY_ACTIVE_ARCH=NO:确保构建所有支持的架构,避免只构建当前设备的架构。
内容的提问来源于stack exchange,提问作者Coder28
相关产品推荐
相关产品推荐

