All Articles

MAC ARM 兼容性问题

1. 前言

年头上更换的M1 MAC ARM架构,当时确实还是遇到了点兼容性问题的。当然全部都是编程方面的问题,不得不夸奖下Rosetta 2,确实强大。因为解决兼容性的时候遇到的一些问题的细节笔记已经丢失,所以这篇文章不会带太多细节,主要是一些指导性、方向性的解释。

2. 兼容性问题

brew

brew也是分arm和x86的,按我目前的经验来说只要装一份arm的就够了,不需要保持两个brew命令同时存在。arm版本的安装操作可以参考:M1芯片Mac上Homebrew安装教程

docker

在使用docker builddocker run的时候都要记得指定--platform来确定镜像是intel还是arm

  • linux/x86_64
  • linux/arm64

特别是run的时候,有的时候会默认去抓取intel的镜像,就导致启动的时候各种问题。

此外还有一个问题,有一些动作比较慢的厂商,比如说couchbase迄今为止都没有arm的image。这就很头痛了,不过没什么好办法,只能慢慢等。

node.js

node的兼容性分两方面,一是node自身的平台及版本管理,另一个就是项目代码里的依赖包的兼容性问题。

nvm

建议使用nvm来进行node的版本管理,官方文档里有关于MAC的相关问题指引:macOS Troubleshooting

node在v15之前的版本是没有arm二进制包的,所以arm的环境nvm安装会从源码开始安装,并得到arm版本的node:

$ node -p process.arch
arm64

January 2021: there are no pre-compiled NodeJS binaries for versions prior to 15.x for Apple’s new M1 chip (arm64 architecture).

官方发布包地址:nodejs.org/dist/latest-v16.x

dep

因为node安装的时候是arm的,然后大量的dep包实际上也是没有arm的二进制包的,所以在编译的时候会遇到各式各样的问题(如果你安装的dep包的版本特别老的话,就更容易遇到,如果版本比较新的话,很多都已经制作了arm对应的binary)。

这里可以按刚才的nvm官方文档里提到的,把整个command line bash环境改成intel的,来进行安装x86的node。这样dep包在安装的时候会和node保持一致,都是x86的,就会更少遇到问题。

# Check what version you're running:
$ node --version
v14.15.4
# Check architecture of the `node` binary:
$ node -p process.arch
arm64
# This confirms that the arch is for the M1 chip, which is causing the problems.
# So we need to uninstall it.
# We can't uninstall the version we are currently using, so switch to another version:
$ nvm install v12.20.1
# Now uninstall the version we want to replace:
$ nvm uninstall v14.15.4
# Launch a new zsh process under the 64-bit X86 architecture:
$ arch -x86_64 zsh
# Install node using nvm. This should download the precompiled x64 binary:
$ nvm install v14.15.4
# Now check that the architecture is correct:
$ node -p process.arch
x64
# It is now safe to return to the arm64 zsh process:
$ exit
# We're back to a native shell:
$ arch
arm64
# And the new version is now available to use:
$ nvm use v14.15.4
Now using node v14.15.4 (npm v6.14.10)

dep包的安装问题就一个指导思想:更新dep包的版本,更新到有arm的binary的版本,就不会有问题了,切忌闷头在那边找源码编译的问题的解决办法。无他,主要是太浪费时间了。。。

没什么感觉的可以看看这些,你就知道有多痛苦了:

EOF