Go

Explain build constraints: the //go:build syntax, filename rules, and common gotchas.

Question 423MediumGo 1.22 to 1.25

Build constraints decide whether a file is part of a package for a given build. There are two mechanisms.

1. //go:build expressions (Go 1.17+). These are boolean expressions with &&, ||, ! and parentheses over GOOS, GOARCH, cgo, unix, goX.Y, compiler names and custom tags. The line must appear before the package clause, preceded only by blank lines and other comments, and gofmt places a blank line after it.

//go:build (linux || darwin) && amd64 && !purego

package fastpath

2. Filename suffixes: *_GOOS.go, *_GOARCH.go, *_GOOS_GOARCH.go, and *_test.go. For example, poll_linux_arm64.go builds only on linux/arm64.

Gotchas:

  • A stray linux.go is fine, but foo_windows.go silently disappears on Linux, which is confusing when the file was not meant to be OS-specific.
  • unix is valid only in //go:build, not as a filename suffix.
  • A typo in a tag name is not an error. The file is just silently excluded.
  • Old // +build lines use different syntax (space means OR, comma means AND). go fix converts them, and go vet reports mismatches.
  • Files starting with _ or . are always ignored.

Check what is actually included with go list -f '{{.GoFiles}} {{.IgnoredGoFiles}}'.

More on Modules, Packages & Tooling

All 36 Modules, Packages & Tooling questions