TL;博士;
将您的库/应用程序的“仅构建活动架构 ( ONLY_ACTIVE_ARCH
)”设置为是,即使对于发布模式也是如此。
在试图找出问题的根本原因时,我意识到了一些关于 Xcode 12 的有趣事实。
Xcode 12 实际上是Apple 芯片的垫脚石,不幸的是,它还不可用(当答案被写出来时)。但是有了这个平台,我们将获得一个基于 arm64 的 macOS,其中模拟器也将在 arm64 架构上运行,这与目前基于 Intel 的x86_64架构不同。
Xcode 通常依赖于“运行目标”来构建它的库/应用程序。因此,当一个模拟器被选为“运行目标”时,它会为可用的模拟器架构构建应用程序,而当一个设备被选为“运行目标”时,它会为设备支持的架构构建应用程序 ( arm*
)。
xcodebuild
,在 Xcode 12+ 构建系统中被arm64
视为支持 Apple 芯片的模拟器的有效架构。So when a simulator is chosen as the run destination, it can potentially try to compile/link your libs/apps against arm64
based simulators, as well. 因此它会发送clang(++)
一些 -target 标志arm64-apple-ios13.0-simulator
,例如 <architecture>-<os>-<sdk>-<destination> 格式,然后 clang 尝试构建/链接基于 arm64 的模拟器,该模拟器最终在基于 Intel 的 Mac 上失败。
但仅针对发布xcodebuild
版本尝试此操作。为什么?因为,“仅构建活动架构 ( )”构建设置通常仅针对“发布”配置设置为“否”。这意味着将尝试为选定的运行目标构建您的库/应用程序的所有架构变体以进行发布构建。对于 Simulator 运行目标,它将同时包含这两者,因为在Xcode 12+ 中也是支持 Apple 芯片的模拟器的受支持架构。ONLY_ACTIVE_ARCH
xcodebuild
x86_64
arm64
arm64
简而言之,Xcode 在任何时候尝试使用命令行xcodebuild
(默认为发布构建,请参阅项目设置的常规选项卡)或其他方式并尝试构建运行目标支持的所有架构变体时,都将无法构建您的应用程序。因此,解决此问题的一个简单解决方法是在您的库/应用程序中将“仅构建活动架构(ONLY_ACTIVE_ARCH
)”设置为“是”,即使对于发布模式也是如此。
如果库作为 Pod 包含并且您可以访问,.podspec
则可以简单地设置:
spec.pod_target_xcconfig = { 'ONLY_ACTIVE_ARCH' => 'YES' }
spec.user_target_xcconfig = { 'ONLY_ACTIVE_ARCH' => 'YES' } # 不推荐
我个人不喜欢第二行,因为pod 不应该污染目标项目,而且它本身可以在目标设置中被覆盖。因此,消费者项目应该有责任通过某种方式覆盖该设置。但是,这对于成功 linting podspecs 可能是必要的。
但是,如果您无权访问.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
我担心的一件事是,当我们实际归档库和应用程序时,这会产生什么影响。在归档应用程序期间,通常采用“发布”配置,因为这将创建一个发布版本,只考虑当前运行目标的活动架构,使用这种方法,我们可能会从目标版本中丢失 armv7、armv7s 等的切片. 但是,我注意到文档说(在附图中突出显示)当我们选择“通用 iOS 设备/任何设备”作为运行目标时,该设置将被忽略,因为它没有定义任何特定的架构。所以我想如果我们存档我们的应用程序选择它作为运行目的地,我们应该会很好。