Go build tag
Go build tag 在 Golang 的源码中被大量使用,因为 Go 要适配各种各样的操作系统和架构,有时候我们做程序在不同操作系统的适配的时候也可以用 build tag,它有两种使用方式,我们一起来看下。
文件注释
Go 编译约束(build constraint),或者直接叫 build tag
, 在 Go 文件中往往是以下面开头的一行:
// +build
它列出了文件被编译的时候是否能够被包含在 package 中的条件。这种约束可能在各种源文件中(不仅在 Go 文件中),但是它必须出现在文件的顶部附近,在空白行或者注释行前面, 当然也要在你声明的 package
语句前面。
为了能够从 package 的文档中区分开 build tag,需要在后面追加一空白行。
如果 build tag 是用 空格
分开的,那么他们之间是 或
的关系。
如果 build tag 是用 逗号
分开的,那么他们之间是 且
的关系。
如果 build tag 前面有 !
, 则是 非
的意思。
Build tag 可以由字母、数字、下划线和点组成。下面是几个 build tag 的例子:
// +build linux,386 darwin,!cgo
它们相当于:
(linux AND 386) OR (darwin AND (NOT cgo))
一个文件可能会有多行 build tag。它们之前是 且
的关系。像下面这样:
// +build linux darwin
// +build amd64
它们相当于:
(linux OR darwin) AND amd64
在特定的构建过程中,它们可以对下面几中情况进行约束:
- 目标操作系统, 由 runtime.GOOS 指定, 可以通过 GOOS 环境变量设置。
- 目标架构, 由 runtime.GOARCH 指定,可以通过 GOARCH 环境变量设置。
- 使用的编译器, 使用 "gc" 或者 "gccgo",(小写的 gc 代表 go compiler)。
- "cgo", 如果 cgo 被支持 (在 'go help environment' 中查看 CGO_ENABLED)。
- Go 发布版本, 比如 "go1.1" 是从 go1.1 起。
- 其他通过 -tags 参数进行指定的额外参数 (请参看 'go help build').
Go Beta版本 或 minior 版本没有单独的构建标记,只能使用类似 go1.16 这样的在 major 版本号。
通过文件名
如果是通过文件名指定 build tag,那么去除扩展名和可能的 _test 后缀之后可能可以匹配到下面几种:
*_GOOS
*_GOARCH
*_GOOS_GOARCH
例如:source_windows_amd64.go,其中 GOOS
和 GOARCH
表示任何已知的操作系统和体系结构值,该文件被认为具有隐式构建约束。
使用 GOOS=android 可以匹配和 GOOS=linux 一样 build tag 的文件,另外还可以匹配 android build tags 的文件。
使用 GOOS=illumos 可以匹配和 GOOS=solaris 一样 build tag 的文件,另外还可以匹配 illumos build tags 的文件。
使用 GOOS=ios 可以匹配和 GOOS=darwin 一样 build tag 的文件,另外还可以匹配 ios build tags 的文件.
为了避免该文件用于编译,你可以使用下面的语句忽略:
// +build ignore
在 Linux 或 OS X 系统上只用 cgo 编译该文件:
// +build linux,cgo darwin,cgo
有时候我们有一些其他系统的实现在另外一个文件中实现了, 这个时候我们可以使用:
// +build !linux,!darwin !cgo
以 dns_windows.go 只有在 Windows 系统构建时才会被使用; 同样的, math_386.s 只有在编译 32-bit x86 的 package 时才会被使用到。