https://inasa.dev/blog/rss.xml

Go | Build Constraints 构建约束

2023-01-02

一个构建约束(构建标签)是文件应包含在包中的条件。构建约束由开始的行注释给出。

//go:build

约束可以出现在任何类型的源文件中(不仅仅是 Go),但它们必须出现在文件顶部附近,前面只有空行和其他行注释。 这些规则意味着在 Go 文件中,构建约束必须出现在 package 子句之前。

为了区分构建约束和包文档,构建约束后面应该跟一个空行。

构建约束注释被评估为包含由 ||、&& 和 ! 组合的构建标记的表达式,运算符和括号。

例如,当满足linux386约束时,或者满足darwincgo不满足时,以下构建约束约束文件构建:

//go:build (linux && 386) || (darwin && !cgo)

一个文件有多个 //go:build 行是错误的。

在特定构建期间,满足以下构建标签:

  • 目标操作系统,由 runtime.GOOS 拼写,使用 GOOS 环境变量设置。
  • 目标体系结构,由 runtime.GOARCH 拼写,使用 GOARCH 环境变量设置。
  • unix,如果 GOOSUnix 或类 Unix 系统。
  • 正在使用的编译器,gcgccgo
  • cgo,如果支持 cgo 命令(请参阅go help environment中的 CGO_ENABLED)。
  • 每个 Go 主要版本的术语,通过当前版本:从 Go 1.1 版开始的“go1.1”,从 Go 1.12 开始的“go1.12”,等等。
  • -tags 标志给出的任何附加标签(参见go help build)。

如果文件名在去除扩展名和可能的 _test 后缀后匹配以下任何模式:

*_GOOS
*_GOARCH
*_GOOS_GOARCH

(示例:source_windows_amd64.go)其中 GOOSGOARCH 分别代表任何已知的操作系统和体系结构值,然后该文件被认为具有需要这些术语的隐式构建约束(除了文件中的任何显式约束之外)。

  • 除了 android 标签和文件之外,使用 GOOS=android 匹配构建标签和文件,就像 GOOS=linux 一样。
  • 除了 illumos 标签和文件之外,使用 GOOS=illumos 匹配构建标签和文件,就像 GOOS=solaris 一样。
  • 除了 ios 标签和文件之外,使用 GOOS=ios 匹配构建标签和文件,就像 GOOS=darwin 一样。

要阻止文件被考虑用于构建:

//go:build ignore

仅在使用 cgo 时构建文件,并且仅在 LinuxOS X 上:

//go:build cgo && (linux || darwin)

这样的文件通常与另一个实现其他系统默认功能的文件配对,在这种情况下会带有约束:

//go:build !(cgo && (linux || darwin))

将文件命名为 dns_windows.go 将导致它仅在为 Windows 构建包时被包含;同样,只有在为 32 位 x86 构建包时才会包含 math_386.s

Go 版本 1.16 及更早版本使用不同的语法来构建约束,带有// +build前缀。 gofmt 命令将在遇到旧语法时添加等效的 //go:build 约束。

例外,下列使用空格,逗号,多行在新版本中已失效:

  • 用空格分隔的构建标记在逻辑上是或
      // +build linux darwin
    
  • 用逗号分隔的构建标记在逻辑上是和
    // +build windows,386
    
  • 在多行上构建约束是逻辑和
    // +build windows
    // +build 386
    

完整的约束标签可以在这里找到