GOLANG 的交叉编译以及 upx 压缩

交叉编译需要知道支持的 GOOS 以及 GOARCH,我们运行 go tool dist list 就可以得到支持的OS 以及硬件平台的组合,以下命令均在 x86_64 平台的 Linux 上运行。

$ go tool dist list|paste - - - - -
aix/ppc64       android/386     android/amd64   android/arm     android/arm64
darwin/386      darwin/amd64    darwin/arm      darwin/arm64    dragonfly/amd64
freebsd/386     freebsd/amd64   freebsd/arm     js/wasm linux/386
linux/amd64     linux/arm       linux/arm64     linux/mips      linux/mips64
linux/mips64le  linux/mipsle    linux/ppc64     linux/ppc64le   linux/s390x
nacl/386        nacl/amd64p32   nacl/arm        netbsd/386      netbsd/amd64
netbsd/arm      openbsd/386     openbsd/amd64   openbsd/arm     plan9/386
plan9/amd64     plan9/arm       solaris/amd64   windows/386     windows/amd64
windows/arm

检查当前的环境变量设置:

$ go env GOOS GOARCH

编译时把 -s -w 传递进 ldflags 我们就可以得到 strip 的二进制文件,以下是 aliyun-cli 项目,编译到 MediaTek MT7621 SoC 的命令,注意 GOARCH 是 mipsle, 也就是小端模式(little endian),然后要指定 softfloat,因为芯片没有硬件浮点处理器。

$ CGO_ENABLED=0 GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -a \
  -ldflags " -s -w -X 'github.com/aliyun/aliyun-cli/cli.Version=3.0.37'" \
   -o out/aliyun-mips main/main.go
然后我们用 upx v3.93 ,请记住一定是这个 3.93 版本,不要用最新版本。 
$ upx --ultra-brute out/aliyun-mips 
得到压缩后的 aliyun-cli 命令行工具,把文件复制到 MT7621 的 OpenWrt 里面,重新命名为 /usr/bin/aliyun 即可

upx 压缩比还是蛮高的,从之前的 25229728 个字节,压缩到了 6355472 字节,压缩到了原文件的 25%,这对捉襟见肘的嵌入式设备而言非常重要。upx v3.96 版本压缩后的文件不能在 MT7621 上跑起来,运行后就一直挂在命令行,没有任何输出。看了 Issue #87 切换到 v3.93 就好了。

在嵌入式设备上有了这个 aliyun 命令行工具,我们就可以定制自己的和阿里云相关的所有脚本了。例如:阿里云 DDNS 脚本

香橙派上,只要 export GOARCH=arm64 就可以编译成功 aliyun cli 了。 然后就可以通过命令行来自动注册香橙派的 DNS 了。