## Build Constraints 构建约束
在开发Go包时,如果依赖特定平台或处理器特定功能时,往往需要提供对应的实现。
go/build包提供了一种命名标记的约定,go工具链允许go包自定义需要被编译进去的go文件,每个文件要么在编译中,要么不在。
构建约束(build constraints)也称作构建标记(build tag)
命名标记的约定有两种方式:
- 文件内首行注释
- 文件名格式
### 文件内首行注释
//go:build XXXXXX
文件首行注释中的go:build XXXXXX标记会被解析为构建约束。 注意,注释后没有空格;且后接一个空白行,也就是构建约束出现在package语句之前。
XXXXXX 列出了在什么情况下,该文件被编译进去。
约束XXXXXX 会被计算为一个表达式,由||, &&, !和括号组成。
比如:
//go:build (linux && 386) || (darwin && !cgo)
// 这个文件在满足 "linux" 和 "386",或满足"darwin"并且"cgo"不满足时,会被编译进去。
在一个构建中,下列词可以作为约束:
- 目标操作系统: 环境变量GOOS
- 目标架构: 环境变量GOARCH
- 使用的编译器: “gc” 或 “gccgo”
- go 版本号: 比如"go1.1",表示从哪个版本号开始
- 任意其他的标签: 在build时,使用-tags标志传递给go工具链
### 文件名格式
构建约束也可以是文件名的一部分,比如 source_windows.go 会在目标操作系统为windows时被编译。
文件名匹配下列任意模式: (比如: source_windows_amd64.go)
*_GOOS
*_GOARCH
*_GOOS_GOARCH
GOOS和GOARCH代表任意已知的操作系统与架构,然后文件会被视为有一个隐式的构建约束。
Go versions 1.16 and earlier used a different syntax for build constraints, with a “// +build” prefix. The gofmt command will add an equivalent //go:build constraint when encountering the older syntax.
Go1.16与之前的版本对约束使用的是另一种不同的语法,使用了一个"// +build"前缀,1.17对构建约束进行了修改。 gofmt命令会在遇到旧的语法时,添加一个等价的//go:build约束。
### 在build时使用约束
目标操作系统和目标架构可以通过设置环境变量来完成:
GOOS=windows GOARCH=amd64 go build main.go
自定义约束
go build -tags tag1,tag2