安装RN过程中的错误及Xcode编译失败过程

公司给配了一个Apple M1芯片电脑,记录一下安装React Native过程中遇到的一些问题,以及安装成功之后Xcode编译错误的解决办法。

一、安装React Native

1、按照中文网步骤安装,Installing boost 卡死

github.com/CocoaPods/c…

解决办法:打开文件 open ~/.cocoapods/repos/master/Specs/9/9/d/boost/1.59.0/boost.podspec.json

修改下载路径

"source": {

"http": "<https://downloads.sourceforge.net/project/boost/boost/1.59.0/boost_1_59_0.tar.gz?r=&ts=1513105136&use_mirror=kent>"

},
复制代码

2、项目clone下来之后,pod install报错

是因为没有 node_modules,

使用npm install 或者 yarn可以下载node_modules文件,但是会非常慢,而且经常报错timeout。

安装cnpm替换npm,npmmirror.com。执行 cnpm install解决此问题。 此方法会出现问题,使用npm install --legacy-peer-deps。

这个提示是RN中文网特别提示的,需要注意 image.png

执行pod install,报错。 原因是 M1芯片适配x86问题,sudo arch -x86_64 gem install ffi 和 arch -x86_64 pod install。 中间还会有一些JSON::ParserError - 416,JSON::ParserError - 451的错误,这些可以根据Cocoapods的github里面的issue解决问题。

最好使用npm生成node_modules文件,进入pod install正常流程

二、Xcode编译失败过程

问题的由来:

Apple发布M1芯片之前,一直使用Intel的芯片,没有出现什么问题。发布M1芯片后,由于两者架构的不同(M1arm64架构,Intelx86_64的架构),导致很多软件运行出现了问题。我们在M1机型中使用Xcode编译模拟器时,可能会碰到如下报错:

building for iOS Simulator, but linking in object file built for iOS, xxxx for architecture arm64
复制代码
ld: symbol(s) not found for architecture x86_64
复制代码

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

解决方案:

1、以Rosetta模式运行Xcode。
以`Rosetta`模式运行是`M1`机器上`x86`软件无法运行的解决方案,它会将`x86`指令转译成`ARM`指令运行,这种转译显然是存在性能损耗的,损耗大概在`20%~30%`,不到万不得已,不推荐使用这种方案。
复制代码
2、修改Build Settings -> Excluded Architectures选项,添加Any iOS Simulator SDK选项,并设置值为arm64。

image.png

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

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

image.png

这种情况下,模拟器和应用会通过XPC进行通信,虽然理论上不会有问题,但通信时间会比较长,导致一些依赖计时器判断的逻辑会出问题,例如滑动手势,加速度的判断会出一些问题,导致模拟器里大部分情况下列表无法触发惯性滚动。

其它问题

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

image.png

最优解

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

以Xcode13为例,在我们创建静态库时,选择真机编译出来的包只包含arm64指令,选择模拟器编译出来的会同时包含arm64x86_64指令。我看一些网上的教程,教别人将模拟器部分的arm64移除,其实大可不必。因为要支持M1机器正常跑模拟器,模拟器必须同时包含arm64x86_64指令。

2019年的WWDCapple提供了一种新的框架封装格式XCFramework。简单理解就是以前使用lipo合并不同指令集的包,现在则使用新的指令合并成XCFramework格式。

猜你喜欢

转载自juejin.im/post/7071089170923880455