You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:39:51