交叉编译

交叉编译 是一个为您工作平台之外的 CPU 架构生成可执行二进制文件的过程。

您从交叉编译获得的主要好处是您不需要第二台或第三台不同架构的机器来生成可执行文件。这意味着您基本上只需要一台机器来做开发。幸运的是,Go 内建了支持交叉编译!

为了这节的目的,我们使用 xCompile.go 的代码来说明交叉编译的过程。xCompile.go 的代码如下:

  1. package main
  2. import (
  3. "fmt"
  4. "runtime"
  5. )
  6. func main() {
  7. fmt.Println("You are using ", runtime.Compiler, " ")
  8. fmt.Println("on a", runtime.GOARCH, "machine")
  9. fmt.Println("with Go version", runtime.Version())
  10. }

在一台 macOS High Sierra 机器上运行 xCompile.go 产生如下输出:

  1. $ go run xCompile.og
  2. You are using gc on a amd64 machine
  3. with Go version go1.10

为了交叉编译 Go 源文件,您需要设置 GOOSGOARCH 环境变量来分别指定目标系统和 CPU 架构,这并不像听起来那么困难。

因此,交叉编译过程如下:

  1. $ env GOOS=linux GOARCH=arm go build xCompile.go
  2. $ file xCompile
  3. xCompile: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, with debug_info, not stripped
  4. $ ./xCompile
  5. -bash: ./xCompile: cannot execute binary file

第一个命令产生一个二进制文件,用于运行在使用 ARM CPU 架构的Linux 机器上,而 file(1) 的输出验证了产生的二进制文件的确是一个不同的 CPU 架构。

由于,我们使用一台有 Intel 处理器的 Debian Linux 机器来演示该例子,所以需要使用正确的 GOARCH 值再执行一次 go build 命令:

  1. $ env GOOS=linux GOARCH=386 go build xCompile.go
  2. $ file xCompile
  3. xCompile: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, with debug_info, not stripped

在 Linux 机器上执行产生的二进制文件将产生如下输出:

  1. $ ./xCompile
  2. You are using gc on a 386 machine
  3. with Go version go1.10
  4. $ go version
  5. go version go1.3.3 linux/amd64
  6. $ go run xCompile.go
  7. You are using gc on a amd64 machine
  8. with Go version go1.3.3

这里第一个需要注意的是,xCompile.go 交叉编译后的二进制文件,打印的Go 版本是编译机的 Go 版本。第二个注意事项是,Linux 机器的 CPU 架构实际是 386 而不是 amd64 用于交叉编译。

您可以在 http://golang.org/doc/install//source找到 GOOSGOARCH 环境变量可用值列表。然而,注意不是所有的 GOOSGOARCH 对都是有效的