从源码编译 golang

首先下载 golang 的代码，可以从 https://golang.org/dl 或者中国的 mirror https://golang.google.cn/dl 下载最新的 go<version>.src.tar.gz. 然后开始编译就可以。

构建方法基本可以参考官方文档 就可以。

构建 bootstrap

go 的构建需要一个可以运行的 go。因此如果我们需要先构建一个 bootstrap 环境。因此我们可以基于交叉编译先构建一个基础环境。

在我们的机器，我们可以到 go-src/src/执行 bootstrap 环境构建

GOOS=linux GOARCH=arm64 ./bootstrap.bash

在和 go-src 同目录下会生成一个 go-${GOOS}-${GOARCH}-bootstrap 目录，也就是 go-linux-arm64-bootstrap ，目录里面的 bin/ 下的 go 在目标环境应该可以跑起来了。

安装依赖

如果需要 cgo，那么我们需要事先安装 gcc

可以更新 mirror。比如如果使用 openwrt，参考 https://mirrors.tuna.tsinghua.edu.cn/help/openwrt/

opkg update
opkg install gcc

构建

首先复制 go-linux-arm64-bootstrap 到目标环境。并且设置 PATH。

export PATH=/root/go-linux-arm64-bootstrap/bin:$PATH

如果我们不需要 cgo，我们可以简单设置 CGO_ENABLED=0 ，然后我们到 go-src 下执行 ./make.bash。

但是如果需要 cgo，那么我们需要保证前面 gcc 或者 clang 是安装过了的。然后同样到 go-src 下执行 ./make.bash。

相关问题

/usr/bin/ld: cannot find -lpthread

错误如下:

# runtime/cgo
/usr/bin/ld: cannot find -lpthread
/usr/bin/ld: cannot find -lpthread

解决方案:

ar -rc /usr/lib/libpthread.a

同理，如果报错

# plugin
/usr/bin/ld: cannot find -ldl

增加 .a 如下:

ar -rc /usr/lib/libdl.a

关于 libdl 的用法参考 https://stackoverflow.com/questions/31155824/dlopen-in-libc-and-libdl，简而言之是 linking 的时候需要的基础库。如果 linking 本身不用它就能跑，就无所谓作为 workaround 即可。