在M1芯片的苹果电脑中使用Xcode编译模拟器时,可能会碰到如下报错:

原因是由于M1模拟器架构是arm64架构,而Intel芯片x86_64的架构,从而导致编译出现了问题。

这些报错,都是是由于项目中存在.a.framework静态库导致的。以前,我们创建静态库时,会分别打包出一份针对真机(arm64)和模拟器的(x86_64),然后将这两份合并成一个包后引入项目中进行使用。在Intel机型上,真机上使用arm64指令,模拟器(x86_64)中使用x86_64指令,所以不存在问题。但是在M1机型上,模拟器是以arm64运行的,显然再以x86_64运行就会出现问题。

有同学可能会想到包中是有arm64指令(真机)的,拿给以arm64运行的模拟器使用不就可以了吗? 实际上xcode底层并不是这样处理的,它真机就找真机的,模拟器就找模拟器的。

解决方案

常用方案

对于这类架构报错问题,网上的资料一般会告诉你两个解决方案:

  1. 以Rosetta模式运行Xcode。

  2. 修改Build Settings -> Excluded Architectures选项,添加Any iOS Simulator SDK选项,并设置值为arm64。图示如下:

  3. 这两种方案都能解决编译问题,但是也都存在问题。

    在iOS12及以后,不再支持iphone5及以下机型,而后续的机型都是arm64架构,所以这里不再对之前的armv6/armv7/armv7s/i386 等指令集进行说明。

    Rosetta方案说明

    Rosetta模式运行是M1机器上x86软件无法运行的解决方案,它会将x86指令转译成ARM指令运行,这种转译显然是存在性能损耗的,损耗大概在20%~30%,详情可参考文章:苹果换芯,成了开发者们的噩梦?https://m.huxiu.com/article/393879.html。

  4. Excluded Architectures方案说明

    修改Excluded Architectures选项也有它的问题。字面意思是排除架构的意思,我们设置在模拟器中排除arm64就能解决模拟器无法编译arm64的问题。

    这样的设置能生效会让人有点费解,我们知道,在intel机型上,模拟器本来就是以x86方式运行的,排除arm64毫无影响。但是在M1机型上,模拟器是以arm64方式运行的,排除了arm64反而能跑,这不是把我的智商摁在地上摩擦么?,但是苹果就是这样干的,当在M1机型上,排除了模拟器的arm64架构后,模拟器还是会以arm64的方式运行,但是模拟器中的app是以x86的方式运行的,对苹果的这个骚操作我们不得不服。图示如下:

  5. 其它问题

    有时候在Excluded Architectures选项中排除了模拟器的arm64指令,依然无法编译通过,那么一般是项目设置和cocoapods的设置不一致导致,设置为一致后一般可以解决问题。可以通过如下配置来解决:在 Podfile 中添加如下设置:

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

    在 Build Settings 中添加如图所示配置,然后重新 pod install:

  6. 最优解

    通过上述内容,我们知道了问题的由来,它是由于项目中存在.a.framework,它们提供的指令集不完整导致的。Apple对于这类问题,也提供了解决方案,请由我细细道来。

      以Xcode13为例,在我们创建静态库时,选择真机编译出来的包只包含arm64指令,选择模拟器编译出来的会同时包含arm64x86_64指令。我看一些网上的教程,教别人将模拟器部分的arm64移除,其实大可不必。因为要支持M1机器正常跑模拟器,模拟器必须同时包含arm64x86_64指令。2019年的WWDCapple提供了一种新的框架封装格式XCFramework。简单理解就是以前使用lipo合并不同指令集的包,现在则使用新的指令合并成XCFramework格式。打包成framework。XCFramework就是把两个不同指令集的framework放入了同一个文件夹(.xcframework),并生成了一个配置文件Info.plist。这样生成的XCFramework就可以完美的解决M1机器无法编译模拟器的问题。

  7. XCFramework的创建指令也很简单:

    .a指令:
    xcodebuild -create-xcframework -library <path> [-headers <path>] [-library <path> [-headers <path>]...] -output <path>
    样例: xcodebuild -create-xcframework -library youpath/xxx.a -headers youpath/xxx -library youpath/xxx.a -headers youpath/TestFramework -output youpath/xxx.xcframework
    .framework指令:
    xcodebuild -create-xcframework -framework <path> [-framework <path>...] -output <path>
    样例: xcodebuild -create-xcframework -framework Release-iphoneos/xxx.framework -framework Release-iphonesimulator/xxx.framework -output xxx.xcframework
  8. 解决M1机型无法编译模拟器的关键就是针对模拟器的包要同时包含arm64x86_64指令集。如果使用只支持x86_64指令集的模拟器包,就算打包成XCFramework也会依然存在这个问题。

    以现在的情况,很多第三方框架,并没有使用XCFramework,而项目中只要有一个框架没有支持模拟器的arm64指令,那么在M1机器上,模拟器只能以Rosetta模式运行应用,对这一块的普遍支持估计要等M1普及以后了。

M1处理器的电脑xcode模拟器编译报错问题详解及解决方案的更多相关文章

  1. 【菜鸟学注入】之MySQL报错注入详解

    本文转自:http://bbs.blackbap.org/forum.php?mod=viewthread&tid=6483&highlight=mysql%2B报错注入 用SQL注入 ...

  2. 关于 xcode 工程编译报错 undefined symbol _res_9_init的解决办法

    将libresolv.dylib 添加到工程引用中(通过build phases中).补充:    _res_9_init定义在resolv.h中,可以参考http://www.opensource. ...

  3. 关于百度鹰眼中 xcode 7 编译报错问题

    请把 这个地方改为 YES 否则demo 不能运行

  4. Ubuntu下Qt编译报错“cannot find -lGL”的解决方案

    转自cannot find -lGL Solved the problem by installing the "libglu1-mesa-dev" package. sudo a ...

  5. 关于vue-clidown到本地后,拷贝文件库到另外一台电脑上npm run dev编译报错的处理

    这些天自己在用vue-cli项目,在家里的电脑下下来后写了一些demo,拿到公司继续开发的时候发现删除node_modules文件,运行npm install和npm run 百度,搜狗了好久都没有找 ...

  6. 新的ipad,用xcode编译报错 dyld_shared_cache_extract_dylibs

    删掉  ~/Library/Developer/Xcode/iOS DeviceSupport/ 这个目录下的特定文件夹就行啦. 其实是因为  device is busy  生成文件夹过程中拔掉了设 ...

  7. Xcode编译报错:< Apple Mach-O Linker Warning > clang: error: no such file or directory: 'xxxx'

    Xcode编译报错概述: clang: error: no such file or directory: 'CoreGraphics' 一般原因是链接库内容导入丢失,这种的排查下target - B ...

  8. 对arm指令集的疑惑,静态库运行,编译报错等问题

    转载自http://www.jianshu.com/p/4a70aa03a4ea?utm_campaign=hugo&utm_medium=reader_share&utm_conte ...

  9. xocde7下导入libsqlite3.tbd编译报错的解决办法

    在xocde7下没有libsqlite3.dylib,只有libsqlite3.tbd,然后我导入了tbd.编译报错error: /Applications/Xcode.app/Contents/De ...

  10. Unity 4.7 导出工程在XCode10.1上编译报错

    Unity 4.7 导出工程在XCode 10.1上编译报错,而在XCode 9.3上是可以正常编译运行的.原因是Unity4.7所依赖的头文件和库文件在XCode10上没有了,解决办法如下,把XCo ...

随机推荐

  1. Redis入门级简单安装使用

      最近突然就想学一下Redis,于是就各种找教程,前两天实际操作了一下,也不是想象中的很难 但是今天想写一个使用Redis的demo,突然就不会使用Redis了,在网上也是查找了半天,还是想起来了点 ...

  2. canvas实现屏幕截图

    1.引入html2canvas.js 2.调用 2.1 <script src="html2canvas.js"></script> 2.2 定义一个div ...

  3. 设计模式 > 单一职责原则

    SOLID原则并非单纯的1个原则,而是由5个设计原则组成的,它们分别是单一职责原则,开闭原则,里氏替换原则,接口隔离原则和依赖反转原则. 单一职责原则(SRP) 定义:一个类或者模块只负责完成一个职责 ...

  4. 不用VS,使用NET 7.0 SDK (v7.0.101)编程c#控制台应用程序方法

    摘要:如果没有vs环境,也可以编程c#控制台应用程序学习c#,方法步骤有下面几个步骤. 1.下载NET 7.0 SDK (v7.0.101)安装 网址https://dotnet.microsoft. ...

  5. windows运行xcopy计划任务 结果是0x4解决方案

    近几天发现一直好好的数据备份计划任务一直返回0x4失败,直接执行bat又是正常的. bat命令中使用的是xcopy,到处找方案没解决. 今天意外在使用另一个命令时,发现提示:网络连接数据超过最大值. ...

  6. #Cisco——配置链路聚合

    Cisco--配置链路聚合 一.什么是链路聚合. 链路聚合(英语:Link Aggregation)是一个计算机网络术语,指将多个物理端口汇聚在一起,形成一个逻辑端口,以实现出/入流量吞吐量在各成员端 ...

  7. HUAWEI--配置单臂路由

    HUAWEI--配置单臂路由 1.在LSW1中创建vlan10和vlan20 [LSW1]vlan batch 10 20 2.接口Eth0/0/2配置trunk,放行vlan10和20,接口Eth0 ...

  8. HttpClient线程池&重试机制

    HttpClientUtils package com.example.http_thread.util; import org.apache.http.HttpEntityEnclosingRequ ...

  9. Gitlab迁移(亲测)

    1. 概述 当前gitlab部署在k8s内,根据基础设施设计此处不合理,需将gitlab迁移至主机部署的gitlab 当前位置:k8s 集群 迁移后位置:云主机部署gitlab 2. Gitlab从K ...

  10. Selenium私房菜系列4 -- Selenium IDE的使用【QQ】

    前面说过,Selenium IDE是Firefox的一个插件,是可以进行脚本录制以及案例转换,所以Selenium IDE+Firebug会成为你日后写测试案例的两大助手(IE下可以使用Seleniu ...