交叉编译Go程序

  • Post author:
  • Post category:IT
  • Post comments:0评论

Go 1.5以前,交叉编译程序还是有一点麻烦的,你需要massive scripts t来编译和宿主机器不同的程序。

正如comes with support for all architectures built in文章中介绍的, Go 1.5可就简单的多了,你只需设置GOOS
GOARCH
两个环境变量就能生成所需平台的Go程序。

比如使用下面的代码测试:

12345678
package mainimport "fmt"import "runtime"func main() {    fmt.Printf("OS: %s\nArchitecture: %s\n", runtime.GOOS, runtime.GOARCH)}

编译它:$ GOOS=darwin GOARCH=386 go build test.go

就可以生成运行在OS X上的程序。

可用的OS和ARCH的值如下:

$GOOS $GOARCH
darwin 386
darwin amd64
darwin arm
darwin arm64
dragonfly amd64
freebsd 386
freebsd amd64
freebsd arm
linux 386
linux amd64
linux arm
linux arm64
linux ppc64
linux ppc64le
netbsd 386
netbsd amd64
netbsd arm
openbsd 386
openbsd amd64
openbsd arm
plan9 386
plan9 amd64
solaris amd64
windows 386
windows amd64

不同的操作系统下的库可能有不同的实现, 比如syscall库。go build没有内置的#define或者预处理器之类的处理平台相关的代码取舍, 而是采用tag和文件后缀的方式实现。

tag方式

tag遵循一下规则

  1. a build tag is evaluated as the OR of space-separated options
  2. each option evaluates as the AND of its comma-separated terms
  3. each term is an alphanumeric word or, preceded by !, its negation

在文件的头部增加tag:

1
// +build darwin freebsd netbsd openbsd

可以有多个tag,之间是AND
的关系

12
// +build linux darwin// +build 386

注意tag和package中间需要有空行分隔,下面的例子是不对的:

12
// +build !linuxpackage mypkg // wrong

文件后缀方式

以_$GOOS.go为后缀的文件只在此平台上编译,其它平台上编译时就当此文件不存在。完整的后缀如:

1
_$GOOS_$GOARCH.go

如syscall_linux_amd64.go,syscall_windows_386.go,syscall_windows.go等。

参考文档

  1. http://golangcookbook.com/chapters/running/cross-compiling/
  2. http://dave.cheney.net/2013/07/09/an-introduction-to-cross-compilation-with-go-1-1
  3. http://dave.cheney.net/2015/03/03/cross-compilation-just-got-a-whole-lot-better-in-go-1-5
  4. https://golang.org/doc/install/source#environment
  5. http://dave.cheney.net/2013/10/12/how-to-use-conditional-compilation-with-the-go-build-tool

发表回复