条件编译和交叉编译
条件编译解决的是一份代码在不同编译平台和不同语言版本的兼容编译问题。
文件名后缀方式
go build 在不读取源文件的情况下可以通过文件名后缀来决定哪些文件参与编译。
后缀主要有以下几种形式
-
_$GOOS.go
-
_$GOARCH.go
-
$GOOS$GOARCH.go_
标签标注方式
通过在文件头增加条件编译标签可以提供更灵活的条件编译。
条件编译标签以 // +build 前缀开始,条件编译标签必须和普通的注释或代码通过空行进行分开,否则编译器无法识别。
条件编译标签类似这样
// +build linux,386 darwin,!cgo
语义为 (linux AND 386) OR (darwin AND (NOT cgo))
// +build linux darwin
// +build 386
语义为:(linux OR darwin) AND 386
规则总结下来就是
空格 ' ' = OR
逗号 ',' = AND
感叹号 '!' = NOT
换行 = OR
具体的条件可以有
-
操作系统,值可以通过 runtime.GOOS 获取
-
CPU 架构,值可以通过 runtime.GOARCH 获取
-
编译器,如 gc,gccgo
-
是否开启 cgo,cgo
-
语言版本,Go 版本如 go1.1,go1.12
-
自定义标签,可以是发布版本号,开发版本等。
build 时指定
Mac 下
# Linux
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
# Win
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go
Linux 下
# Mac
SET CGO_ENABLED=0
SET GOOS=darwin
SET GOARCH=amd64
go build main.go
# Win
SET CGO_ENABLED=0
SET GOOS=linux
SET GOARCH=amd64
go build main.go
Win 下
需要写一个批处理程序,在里面去设置,因为windows 下的 terminal 不支持shell , 这跟 Mac 和 Linux下的有点不同
# Mac
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build main.go
# Linux
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
GOOS:目标平台的操作系统(darwin、freebsd、linux、windows)GOARCH:目标平台的体系架构(386、amd64、arm)交叉编译不支持 CGO 所以要禁用它。
GOOS 和 GOARCH 的值成对出现,而且只能是下面对应的值
$GOOS $GOARCH
android arm
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
linux mips
linux mipsle
linux mips64
linux mips64le
linux s390x
netbsd 386
netbsd amd64
netbsd arm
openbsd 386
openbsd amd64
openbsd arm
plan9 386
plan9 amd64
solaris amd64
windows 386
windows amd64
32 位程序就用 386 代替上面示例中的 amd64。
参考
[Go 编程: 交叉编译 vs 条件编译](Go 编程: 交叉编译 vs 条件编译)
Build Constraints
Read other posts