M系列Mac上的模拟器运行比较旧的项目报错
M系列Mac上的模拟器运行比较旧的项目报错
一、编译iOS相关有关架构的一些配置:
1、Build Active Architecture Only
: 如果你将其设置为 “Yes”,那么 Xcode 只会为当前活动的架构(即你正在使用的设备或模拟器的架构)构建你的应用。这可以加快构建时间,但是生成的二进制文件可能无法在其他架构的设备或模拟器上运行。
2、Valid Architectures
:从 Xcode 12 开始,”Valid Architectures” 设置被移除了,因为 Xcode 现在会自动确定有效的架构。对于大多数项目,你应该不需要手动设置这个选项。
3、Architectures
:通常都是标准架构,Xcode 现在会自动确定有效的架构。替代以前的Valid Architectures
。
4、Excluded Architectures
:被排除的架构,用于指定在构建过程中应该被忽略的 CPU 架构。当你构建一个应用时,Xcode 会基于你的设置为一个或多个特定的 CPU 架构生成二进制代码。例如,你可能会生成适用于ARM64(用于大多数现代 iOS 设备)或 x86_64(用于模拟器在 Intel Mac 上运行)的代码。如果你在 “Excluded Architectures” 中指定了某个架构,那么 Xcode 在构建过程中就不会为该架构生成代码。例如,如果你在 “Excluded Architectures” 中指定了 “arm64”,那么你的应用就只会为 x86_64 架构(也就是模拟器)生成代码,但是你就不能将其部署到使用 ARM64 架构的设备上。
二、编译一个特定架构的库的步骤:
在 Xcode 中,你可以在工具栏的界面右上角找到 “Set the active scheme”(设定活动方案)的选项。这个选项可以让你选择目标设备。
打开你的 Xcode 项目。
在 Xcode 的工具栏界面右上角,你可以看到一个类似于 iOS 设备或者模拟器名称的下拉菜单,这就是 “Set the active scheme” 的选项。
点击这个下拉菜单,它会显示出所有可用的设备和模拟器。
在这个列表中,选择你想要的模拟器。例如,你可以选择 “iPhone 12 Pro Max Simulator”。
确保你选择了正确的模拟器后,点击 “Run” 或 “Build”,Xcode 就会为这个模拟器生成二进制文件。
三、问题现场:
Xcode工程,依赖n个库,其中一个老库是个.a的静态库。这个静态库是在老的Intel Mac上编译的fat架构二进制文件(X86_64、arm64)。该项目在Intel的模拟器上能正常运行,在M1 Mac上无法正常运行,真机都是可以的。
四、分析:
一个库如果包含了arm64和x86_64的架构,理论上是可以在模拟器和真机上运行的。但是,要注意的是,真机的arm64和模拟器的arm64是不同的。当你在M1 Mac上运行模拟器时,你需要一个针对模拟器的arm64版本的库,这个版本的库是在Xcode 12以及更高版本中引入的,也就是说老的Xcode编译的真机的arm64想给模拟器用行不通。
具体来说虽然 M1 Mac 和 iOS 设备都使用 arm64 架构的 CPU,但它们的 ABI(Application Binary Interface)并不完全相同。这主要是因为,虽然它们的硬件架构相同,但操作系统和其他系统级别的差异导致了 ABI 的不同。因此,即使你的库包含了用于真机的 arm64 代码,你仍然需要为模拟器编译一个包含 arm64 代码的版本。而这个模拟器版本的 arm64 代码必须在 M1 Mac 上编译,因为只有 M1 Mac 才能运行 iOS 模拟器的 arm64 代码。
所以,如果你的库包含的是真机的arm64,而不是模拟器的arm64,那么它将无法在M1 Mac的模拟器上运行。
五、解决方案:
利用Mac的Rosetta 2 来转译 x86_64 代码为 ARM64 代码,我们的老库有x86_64架构,也能无需任何配置在Intel的Mac上运行,所以我们屏蔽掉arm64架构,在编译的时候会定位到x86_64架构链接。
1 |
|
上面代码会让所有的pod库的iphonesimulatorSDK排除arm64也就是x86_64架构,真机的时候还是包含arm64。
1、真机:主工程EXCLUDED_ARCHS
不做任何设置,通过默认的架构选项就是arm64,pod库也有arm64,能正常运行;
2、跑模拟器:主工程EXCLUDED_ARCHS
不做任何设置,通过默认的架构选项模拟器的arm64,pod库再模拟器sdk上是x86_64,无法链接,运行报错;
操作:直接双击主工程的Excluded Architectures
的value项目,输入arm64
1、真机:主工程EXCLUDED_ARCHS
设置arm64,明显真机的架构都没了,不能正常运行;
2、跑模拟器:主工程EXCLUDED_ARCHS
设置arm64,自动选择主工程是x86_64了,pod库再模拟器sdk上是x86_64,模拟器能正常运行,通过Rosetta 2
;
六、合理的设置方案:
模拟器上exclude arm64,真机上不用exclude任何架构。在Excluded Architectures
展开,在Debug上点击➕,选择Any iOS SDK, 设置空。如下图:
