在M1 Mac上编译使用arm64原生go
go会在2021年2月发布的1.16版中正式Apple Silicon,即arm64架构的Mac操作系统,虽然还未正式发布,但目前go 1.16版已经进入feature freeze期,只是会再修修bug,改进文档等,喜欢尝鲜的朋友,其实已经可以在m1 mac里面下载go最新的源码,然后编译原生arm64版的go出来。
以下操作我全部在m1 mac mini上完成;并假设go的工具链安装在 $HOME/goroots 路径下。
mac上需要确保安装有 rosetta 2(https://support.apple.com/en-us/HT211861)。
安装go 1.15
自go 1.4开始,go的编译器已经实现了自举,即我们可以使用go本身来编译go,那么,为了在mac上使用arm64的go 1.16尝鲜版,我们首先需要amd64的go 1.15。
说是安装,但其实只需要下载就可以了:
mkdir $HOME/goroots
cd $HOME/goroots
wget https://dl.google.com/go/go1.15.6.darwin-amd64.tar.gz
tar xzf go1.15.6.darwin-amd64.tar.gz
获得go源码
直接clone go源码仓库:
cd $HOME/goroots
git clone https://go.googlesource.com/go gosource
克隆github上的go源码镜像(github.com/golang/go)也行。
clone出来之后目前master分支便是 1.16 的预发布分支。
预编译darwin/arm64
要编译go的话,需要先预编译 bootstrap 响应的工具链,这个工具链本身也是需要是arm64版,不然最后make出来的还会是x86。
cd $HOME/goroots/gosource/src
arch --x86_64 env GOROOT_BOOTSTRAP=$HOME/goroots/go GODEBUG=asyncpreemptoff=1 GOOS=darwin GOARCH=arm64 ./bootstrap.bash
注意上面的编译环境变量参数中有 GODEBUG=asyncpreemptoff=1 ,这是因为我们的go 1.15是amd64版,直接在m1 mac中运行时需要依赖 rosetta 2,而目前似乎rosetta 2对于go的协程异步抢占还有bug,因此需要关闭;否则编译时会死锁并出现错误:
rosetta error: ulock_wait failure: 105
完成这步后,我们便可在 $HOME/goroots/go-darwin-arm64-bootstrap 路径下获得编译完整go的arm64工具链
编译arm64原生go
cd $HOME/goroots/gosource/src
arch --arm64e env GOROOT_BOOTSTRAP=$HOME/goroots/go-darwin-arm64-bootstrap ./make.bash
这样我们便可在 $HOME/goroots/gosource/bin/go 获得arm64的go啦~export $HOME/goroots/gosource/bin 路径去PATH,便可以在系统中使用原生的go了 :)
搞定~