這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
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遵循一下規則
- a build tag is evaluated as the OR of space-separated options
- each option evaluates as the AND of its comma-separated terms
- 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為尾碼的檔案只在此平台上編譯,其它平台上編譯時間就當此檔案不存在。完整的尾碼如:
如syscall_linux_amd64.go,syscall_windows_386.go,syscall_windows.go等。
參考文檔
- http://golangcookbook.com/chapters/running/cross-compiling/
- http://dave.cheney.net/2013/07/09/an-introduction-to-cross-compilation-with-go-1-1
- http://dave.cheney.net/2015/03/03/cross-compilation-just-got-a-whole-lot-better-in-go-1-5
- https://golang.org/doc/install/source#environment
- http://dave.cheney.net/2013/10/12/how-to-use-conditional-compilation-with-the-go-build-tool