Golang 学习笔记——交叉编译 & 部署

用 Golang 写了一个小功能,想部署到的服务器上。这里就简单记录一下过程吧。
我现在用的 Go 的版本是1.5.1,直接用安装包安装的,Mac OS X 平台。

交叉编译

Golang 的交叉编译还是蛮方便的。
首先用go env查看一下本机的 go 环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/yibo/golang/lib:/Users/yibo/golang/work"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GO15VENDOREXPERIMENT=""
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fno-common"
CXX="clang++"
CGO_ENABLED="1"

交叉编译涉及到两个环境变量——GOOSGOARCH,别代表 Target Host OS 和 Target Host ARCH。我的 Go 是采用安装包安装的,默认情况的这两个环境变量和本机的GOHOSTOSGOHOSTARCH是一样的。

明白了这两个环境变量后就可以开搞了,先编译一个 Linux 下的

1
2
$ cd $GOPATH/src
$ GOOS=linux GOARCH=amd64 go build -o example_linux example.com/your/package

然后你就能在当前目录下看到一个名为example_linux的可执行文件了,如果想看编译过程的详细信息,go build的时候加上-x

p.s. 网上很多文章都说交叉编译的话需要先建立交叉编译器所需要的平台和架构,

1
2
$ cd $GOROOT/src //或者是bin
$ GOOS=linux GOARCH=amd64 ./make.bash`

我不知道是不是因为版本的缘故,我并没有这个步骤就能直接编译出 Linux 和 Windows 下的可执行文件。当我试着去$GOROOT/src/make.bash的时候,反而报错了

1
2
3
4
5
6
$ ./make.bash
##### Building Go bootstrap tool.
cmd/dist
ERROR: Cannot find /Users/yibo/go1.4/bin/go.
Set $GOROOT_BOOTSTRAP to a working Go tree >= Go 1.4.
./make.bash:行121: /Users/yibo/go1.4/bin/go: No such file or directory

因为 Go 1.5 及之后版本彻底告别了 C 代码,用 Go 构建的 Go,构建 Go 1.n(n≥5)需要用 Go 1.4,并且将环境变量GOROOT_BOOTSTRAP指向 Go 1.4(注意,将GOROOT_BOOTSTRAP指向GOROOT是行不通滴),具体的可以参见https://golang.org/s/go15bootstrap。因为我没有装 Go 1.4,反正也能交叉编译,也就不纠结了。

交叉编译 Windows 的无非就是改下GOOSGOARCH,如下

1
$ GOOS=windows GOARCH=amd64 go build -o example.exe example.com/your/package

部署

部署本来没什么好讲的,Go 的部署简单无比,直接把编译好的那个可执行文件拉到服务器上,改下权限就能跑起来了

1
2
3
4
5
6
7
// local
$ scp example_linux root@host:/path
$ ssh root@host
// server
# cd /path
# chmod +x example_linux
# ./example_linux

不过 Go 有个 bug,无法成为守护进程(Daemonize)——也不知现在解决了没有。详细见 https://code.google.com/p/go/issues/detail?id=227Golang fork process

也有几种实现 Go 语言 daemon 的方案,不过得先了解 Linux 的守护进程是咋实现的。对此我也不是太了解,就采用了另一种方式,用第三方的工具来管理(也是谢大《Go Web 编程》书中推荐的)—— Supervisor。

p.s. 其实想简单点的话,也可以用nohup commend &来后台运行,至于其与 daemon 的区别,可以参考 linux 的nohup & 和daemon 总结

Supervisor

Supervisor 是用 Python 实现的一个进程管理工具,它会帮你把它转成 Daemon 程序(并且它要求被管理的程序必须是非 Daemon 的)

因为后边我又将 Supervisor 用于管理其他进程,并做更深一步的使用,故将其内容从本文拆分出去,传送门在此:Supervisor 基础

参考
Golang跨平台交叉编译