告别构建错误, iOS 开发架构难题全面解析, 避免 CPU 架构陷阱

这里每天分享一个 iOS 的新知识,快来关注我吧

前言

如果你经常开发 iOS 中的第三方框架,那么你可能会遇到以下错误:

"Could not find module *** for target 'x86_64-apple-ios-simulator'."

或者:

"building for iOS Simulator, but linking in dylib built for iOS, file, '.../Frameworks/xxx.framework/xxx' for architecture arm64."

要解决这个问题,我们需要了解 CPU 架构和 Xcode 构建设置的一些知识,今天我们就来聊聊这个。

理解 CPU 架构

每个 CPU 都有一组可以执行的指令。这些指令主要分为两种类型:

CISC(复杂指令集计算)

  • 复杂且强大的指令。

  • 每条指令执行多个任务。

  • 例如:x86 处理器(由 Intel 和 AMD 使用)。

RISC(精简指令集计算)

  • 简单且快速的指令。

  • 每条指令执行一个任务。

  • 例如:ARM 处理器(由 Qualcomm、MediaTek 和苹果的 M1 芯片使用)。

什么是 32 位和 64 位

  • 32 位:一次可以处理 32 位数据。

  • 64 位:一次可以处理 64 位数据,允许更多的计算能力和内存使用。

常见架构

  • x86:Intel 和 AMD 使用的 32 位架构。

  • x86_64:x86 的 64 位版本,更强大,能处理更多数据。

  • ARM:Qualcomm 和 MediaTek 使用的 32 位架构。

  • ARM64:ARM 的 64 位版本,更强大,苹果的 M1 芯片使用。

主要的制造商

  • Intel 和 AMD:制造 x86 和 x86_64 处理器。

  • Qualcomm 和 MediaTek:制造 ARM 和 ARM64 处理器。

  • Apple:在 Apple Silicon 系列(M1、M1、M2、M3、M4 等)Mac 中使用 ARM64 处理器。

向 M 系列过渡与 Rosetta 的作用

M 系列处理器的引入,始于 M1,标志着苹果及其生态系统的重大转变。由于 M 系列基于 ARM,现有为 x86 构建的软件无法在这些新芯片上原生运行。为弥补这一差距,苹果推出了 Rosetta,它是一种兼容层,主要作用是允许 x86 软件在 M 系列处理器上运行。

M1 MacBooks 推出后,Xcode 最初就是使用 Rosetta 支持 x86 应用程序。

虽然这让开发者可以继续无缝工作,但 Rosetta 只是 Apple Silicon 过渡期的临时解决方案。随着 Xcode 12 的推出,苹果使 Xcode 能够在 ARM 上原生运行,全力支持 M 系列 MacBooks,而不再依赖于 Rosetta。

iOS 14 之前的模拟器仅限于 x86,并通过 Rosetta 在 M 系列 Mac 上运行。自 iOS 14 起,模拟器更新支持 ARM 和 x86,这意味着虽然模拟器可以在 M 系列 Mac 上原生运行,但未为 ARM 优化的应用程序仍会通过 Rosetta 运行。这种双重架构支持确保了过渡期间的兼容性和性能。

要检查你的应用程序正在使用哪种架构,你可以使用活动监视器。在活动监视器中,有一个名为"Kind"的列,显示应用程序是运行在 Intel(x86)还是 Apple(ARM)架构下。这一功能仅在 M 系列 Mac 上可用。

Apple 物理设备架构

  • arm64:也称为 AArch64,现代 64 位 iOS 设备(iPhone 5S 及更新机型),包括 A7、A8、A9、A10 和 A11 芯片的设备。

  • arm64e:较新的 64 位 iOS 设备,带有 A12 仿生芯片及更新版本(例如,iPhone XS、XR、11、12、13 等)。

  • armv7:较旧的 32 位 iOS 设备(iPhone 3GS、4、4S)。

  • armv7s:略新的 32 位设备(iPhone 5、5C)。

Apple 模拟器架构

  • x86_64:基于 Intel 的 Mac 上的模拟器。

  • i386:用于较旧 iOS 版本的 32 位模拟器(主要是遗留支持)。

  • arm64:Apple Silicon(M1、M2)Mac 上的模拟器。

在了解了 CPU 架构基础知识、列出设备和模拟器架构,并讨论了 M 系列的历史和 Rosetta 的作用后,为解决之前提到的错误,我们需要知道如何找出我们集成的框架所支持的架构。

此外,我们需要调整构建设置,如 EXCLUDED_ARCHS 和 ONLY_ACTIVE_ARCH。接下来聊聊这些。

确定支持的架构

要确定 .xcframework 支持的架构,我们可以在终端中使用 lipo -info 命令。通过检查 .xcframework 中的目录,我们可以识别出支持哪些架构。以下是使用 lipo -info ~/Downloads/Bugly.framework/Bugly 查看 Bugly 2.6.0 版本的示例:

根据命令输出可以看出 Bugly 2.6.0 版本支持 armv7、i386、x86_64 和 arm64 架构。

理解 EXCLUDED_ARCHS 和 ONLY_ACTIVE_ARCH

EXCLUDED_ARCHS

  • 定义:Xcode 中的一个构建设置,用于指定在构建目标时要排除的架构。

  • 用途:排除某些架构以避免兼容性问题或不必要的构建。

  • 示例EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64 在为 iOS 模拟器构建时排除 arm64 架构,以确保兼容基于 Intel 的 Mac 上的 x86_64 模拟器。

ONLY_ACTIVE_ARCH

  • 定义:一个构建设置,决定 Xcode 是仅构建活动架构还是所有指定架构。

  • 用途:通过仅构建活动架构来加快开发过程中的构建速度。

  • 示例ONLY_ACTIVE_ARCH = YES 仅构建活动架构,在开发过程中减少构建时间。通常在 Debug 配置中设置为 YES,在 Release 配置中设置为 NO,以确保最终构建支持所有所需架构。

说白了一个是黑名单,一个是白名单。

之前提到的错误

错误消息"Could not find module *** for target 'x86_64-apple-ios-simulator'."通常表示我们尝试使用的框架或模块不可用于我们目标的架构,它需要原生运行而不是使用 Rosetta,但我们试图导入仅为 x86_64 构建的框架或可测试应用:

解决方法

我们可以实施一种变通方法来让测试目标运行,但这取决于使用的机器:

  • Apple Silicon M 系列:在 EXCLUDED_ARCHS 中排除 arm64。
  • 基于 Intel 的:在 Debug 模式下使用"仅构建活动架构",这将允许项目成功运行。

更好的解决方案

如果你可以控制框架的构建,建议打包的时候支持缺失的架构,特别是 arm64 模拟架构。

在分发的时候,优先使用 ios-arm64_i386_x86_64-simulator 或 ios-arm64_x86_64-simulator,更旧的模拟器一般就不用支持了。

如果你无法控制框架的构建,也无法联系开发者,你需要使用 EXCLUDED_ARCHS 排除缺失的架构。然而,这种方法可能限制你只能在物理设备上运行,特别是对于 Apple M 系列。此外,它要求你在使用此框架的所有依赖项中排除缺失的架构。例如,如果你使用的核心框架依赖于缺少架构的库,则核心框架和导入核心的项目都必须排除相同的架构。因此,在解决此类错误时要谨慎和耐心。

总结

希望今天的分享能帮助你解决在开发过程中遇到的架构问题。如果你有任何疑问,欢迎留言讨论。

这里每天分享一个 iOS 的新知识,快来关注我吧

本文同步自微信公众号 "iOS新知",每天准时分享一个新知识,这里只是同步,想要及时学到就来关注我吧!

相关推荐
报错小能手13 小时前
ios开发方向——swift错误处理:do/try/catch、Result、throws
开发语言·学习·ios·swift
程序员老刘13 小时前
放弃折腾后端服务器后,这才是独立开发MVP的最优解
flutter·客户端·firebase
小夏子_riotous15 小时前
openstack的使用——5. Swift服务的基本使用
linux·运维·开发语言·分布式·云计算·openstack·swift
开心就好202518 小时前
Flutter iOS应用混淆与安全配置详细文档指南
后端·ios
mCell19 小时前
MacOS 下实现 AI 操控电脑(Computer Use)的思考
macos·agent·swift
开心就好202519 小时前
苹果iOS应用开发上架与推广完整教程
后端·ios
用户693717500138420 小时前
XChat 为什么选择 Rust 语言开发
android·前端·ios
MonkeyKing20 小时前
Objective-C Runtime 完整机制:objc_class /cache/bits 源码解析
前端·ios
用户794572239541320 小时前
【DGCharts】iOS 图表渲染事实标准——8 种图表类型、高度可定制,3 行代码画出一条折线
swiftui·swift
秋雨梧桐叶落莳21 小时前
【iOS】 AutoLayout初步学习
学习·macos·ios·objective-c·cocoa·xcode