我正在尝试在Xcode 12(beta 5)中构建一个大型(正在开发Xcode 11!)项目,为iOS 14做准备。代码库以前是Objective-C中的,但现在它同时包含Objective-C和Swift,并使用Objective-C或Swift的pod。

我已经推出了支持Xcode 12的CocoaPods新测试版(目前为1.10.0.beta 2)。

Pod安装成功。当我进行构建时,在pod框架上出现以下错误:

为iOS模拟器构建,但链接到为iOS构建的对象文件中,用于体系结构arm64

以及可能的错误:

无法加载目标“arm64-apple-ios11.0”的标准库

当我在框架上运行lipo-info时,它有:armv7s armv7 i386 x86_64 arm64。

此前,该项目的有效架构设置为:armv7、armv7s和arm64。

在Xcode 12中,根据苹果的文档,该设置将消失。架构设置为$(ARCH_STANDARD)。我在排除的架构中没有任何设置。

这里可能发生了什么?我还没能用一个更简单的项目重现这一点。


当前回答

当我遇到这个问题时,我正试图构建xcFramework。没有什么帮助,但我设法用lipo解决了这个问题,并分享了我的脚本:

OUTPUT_DIR_PATH="${PROJECT_DIR}/XCFramework"

function archivePathSimulator {
    local DIR=${OUTPUT_DIR_PATH}/archives/"${1}-SIMULATOR"
    echo "${DIR}"
}

function archivePathDevice {
    local DIR=${OUTPUT_DIR_PATH}/archives/"${1}-DEVICE"
    echo "${DIR}"
}

function archive {
    echo "▸ Starts archiving the scheme: ${1} for destination: ${2};\n▸ Archive path: ${3}.xcarchive"
    xcodebuild clean archive \
    -project "${PROJECT_NAME}.xcodeproj" \
    -scheme ${1} \
    -configuration ${CONFIGURATION} \
    -destination "${2}" \
    -archivePath "${3}" \
    SKIP_INSTALL=NO \
    OBJROOT="${OBJROOT}/DependentBuilds" \
    BUILD_LIBRARY_FOR_DISTRIBUTION=YES | xcpretty
}

# Builds archive for iOS simulator & device
function buildArchive {
    SCHEME=${1}

    archive $SCHEME "generic/platform=iOS Simulator" $(archivePathSimulator $SCHEME)
    archive $SCHEME "generic/platform=iOS" $(archivePathDevice $SCHEME)
}

# Creates xc framework
function createXCFramework {
    FRAMEWORK_ARCHIVE_PATH_POSTFIX=".xcarchive/Products/Library/Frameworks"
    FRAMEWORK_SIMULATOR_DIR="$(archivePathSimulator $1)${FRAMEWORK_ARCHIVE_PATH_POSTFIX}"
    FRAMEWORK_DEVICE_DIR="$(archivePathDevice $1)${FRAMEWORK_ARCHIVE_PATH_POSTFIX}"

    echo "Removing ${FRAMEWORK_SIMULATOR_DIR}/${1}.framework/${1}"

    if lipo "${FRAMEWORK_SIMULATOR_DIR}/${1}.framework/${1}" -verify_arch "arm64"; then
        echo "Removing arm64"
        lipo -remove "arm64" -output "${FRAMEWORK_SIMULATOR_DIR}/${1}.framework/${1}" "${FRAMEWORK_SIMULATOR_DIR}/${1}.framework/${1}"
    fi

    xcodebuild -create-xcframework \
               -framework ${FRAMEWORK_SIMULATOR_DIR}/${1}.framework \
               -framework ${FRAMEWORK_DEVICE_DIR}/${1}.framework \
               -output ${OUTPUT_DIR_PATH}/xcframeworks/${1}.xcframework
}

echo "#####################"
echo "▸ Cleaning the dir: ${OUTPUT_DIR_PATH}"
rm -rf $OUTPUT_DIR_PATH

DYNAMIC_FRAMEWORK="${PROJECT_NAME}"

echo "▸ Archive $DYNAMIC_FRAMEWORK"
buildArchive ${DYNAMIC_FRAMEWORK}

echo "▸ Create $DYNAMIC_FRAMEWORK.xcframework"
createXCFramework ${DYNAMIC_FRAMEWORK}

其他回答

在我的案例中,错误是由GTMAppAuth引发的,我在Flutter项目中使用的是谷歌签名。

解决方案:您必须转到该包,然后在“仅构建活动体系结构”中单击“是”。

在我的案例中:Xcode 12

我在EXCLUDED_ARCHS上设置了空值,并设置了ONLY_ACTIVE_ARCH Debug=YES Release=NO Project的Build Setting

我在我的播客文件中包括了这一点:

post_install do |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
        end
    end
end

它在我的模拟器iPhone 8(iOS 12)和iPhone 11 Pro Max(iOS 14)以及我的设备iPhone 7 Plus(iOS 13.4)上运行。

所有这些答案中隐藏的宝石

我在主要项目的目标中更改了“排除架构”,但在PODS项目中没有更改。这是一块真正隐藏的宝石。我已经处理这个问题好几个星期了。

TL;博士;

将库/应用程序的“仅构建活动体系结构(Only_Active_ARCH)”设置为“是”,即使在发布模式下也是如此。


在试图确定问题的根本原因时,我意识到Xcode 12的一些有趣的事实。

Xcode 12实际上是Apple silicon的垫脚石,遗憾的是(当答案写出来时)它还没有问世。但有了这个平台,我们将得到一个基于arm64的macOS,模拟器也将在arm64架构上运行,这与目前基于Intel的x86_64架构不同。Xcode通常依赖于“运行目标”来构建其库/应用程序。因此,当模拟器被选择为“运行目的地”时,它会为可用的模拟器架构构建应用程序,而当设备被选为“运行目标”时,则会为设备支持的架构(arm*)构建应用程序。Xcode 12+构建系统中的xcodebuild认为arm64是模拟器支持Apple silicon的有效架构。因此,当选择模拟器作为运行目标时,它也可以尝试编译/链接基于arm64的模拟器的libs/apps。因此,它以<architecture>-<os>-<sdk>-<destination>格式发送clang(++)一些目标标志,如arm64-apple-ios13.0-simulator,clang尝试构建/链接基于arm64的模拟器,最终在基于Intel的Mac上失败。但xcodebuild仅对Release版本尝试此操作。为什么?因为,对于“Release”配置,“Build Active Architecture Only(Only_Active_ARCH)”构建设置通常设置为“No”。这意味着xcodebuild将尝试为发布版本的选定运行目标构建libs/apps的所有架构变体。对于模拟器运行目的地,现在它将包括x86_64和arm64,因为Xcode 12+中的arm64也是模拟器支持Apple silicon的支持架构。

简单地说,Xcode在尝试命令行xcodebuild(默认为releasebuild,请参见项目设置的常规选项卡)或其他方式并尝试构建运行目标支持的所有体系结构变体时,将无法构建应用程序。因此,解决此问题的一个简单方法是在库/应用程序中将“仅构建活动体系结构(Only_Active_ARCH)”设置为“是”,即使在发布模式下也是如此。

如果库包含为Pods,并且您可以访问.podspec,则可以简单地设置:

spec.pod_target_xcconfig={“ONLY_ACTIVE_ARCH”=>“是”}

spec_user_target_xcconfig={'ONLY_ACTIVE_ARCH'=>'YES'}#否推荐

我个人不喜欢第二行,因为pods不应该污染目标项目,而且它本身可以在目标设置中被覆盖。因此,消费者项目应该负责以某种方式覆盖设置。然而,这可能是成功的柱脚过梁所必需的。

但是,如果您没有访问.podspec的权限,您可以在安装pod期间始终更新设置:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings["ONLY_ACTIVE_ARCH"] = "YES"
    end
  end
end

我担心的一件事是,当我们实际归档库和应用程序时,这会产生什么影响。在归档过程中,应用程序通常采用“Release”配置,因为这将创建一个只考虑当前运行目标的活动体系结构的版本构建,因此使用这种方法,我们可能会从目标构建中丢失armv7、armv7等的切片。然而,我注意到文档中说(在所附图片中突出显示),当我们选择“通用iOS设备/任何设备”作为运行目标时,将忽略此设置,因为它没有定义任何特定的架构。所以我想,如果我们将我们的应用程序归档,并将其作为跑步目的地,我们应该会很好。

1.将arm64添加到构建设置->排除所有目标中的体系结构。

2.关闭Xcode并按照以下步骤打开

右键单击Finder中的Xcode显示简介用Rosetta打开