Go的交叉编译

Go的交叉编译

转自鸟窝

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

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

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

package main

import "fmt"
import "runtime"

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

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

*** 跨系统编译
	Mac下编译Linux和Windows平台64位可执行程序需要设置
		Linux
			CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build;
		Windows	
			CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build;
	
	Linux下编译Mac和Windows平台64位可执行程序
		Mac
			CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build;
		Windows
			CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build;
	Windows下编译Mac和Linux平台64位可执行程序
		Mac
			SET CGO_ENABLED=0  // 禁用CGO
			SET GOOS=darwin		// 目标平台设定
			SET GOARCH=amd64  	// 64位系统
			go build
		Linux
			SET CGO_ENABLED=0
			SET GOOS=linux 
			SET GOARCH=amd64
			go build
	

就可以生成运行在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:

// +build darwin freebsd netbsd openbsd

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

// +build linux darwin
// +build 386

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

// +build !linux
package mypkg // wrong

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

_$GOOS_$GOARCH.go

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

posted @ 2020-12-16 14:00  Binb  阅读(747)  评论(0编辑  收藏  举报