17 — Build and toolchain¶
The go command beyond go run: which files a build compiles, what it copies into the binary, what the linker can write into a variable, what runs only when you ask, and why the same source gives the same bytes. Every claim is measured on Go 1.25 by a script that makes a throwaway module in a temporary directory, the way The race detector does, and prints nothing that differs between the Linux and Mac runners that check it — no GOOS, no version, no path, no size.
Read The race detector first for the shape of a driver, and keep Subtests and table tests nearby: go test and go vet read the same build constraints and the same generated files as go build.
| Lesson | The one thing |
|---|---|
//go:build chooses which files are compiled |
fast and !fast files define one function twice and only one is ever compiled; go list -f '{{.GoFiles}}' shows the choice for any GOOS without building, and go vet needs the same -tags |
//go:embed puts files in the binary |
a string, a []byte and an embed.FS are filled at build time; the sources are deleted and the binary still has them, in sorted order |
-ldflags -X sets a variable at link time |
dev becomes 1.4.2 without a source change; only a string, only package-level, only with a constant initialiser — an int is refused, a misspelt name is silent |
go generate runs a command you name |
go build before go generate is an undefined error; the generator sees $GOFILE, $GOPACKAGE and $GOLINE, and writes a first line every tool recognises |
Builds are reproducible with -trimpath |
two directories give identical bytes with -trimpath and different ones without; a git checkout stamps the commit in, and go env -w is shown without touching your configuration |
| Companion | What it holds |
|---|---|
| The compiler errors | go.mod file not found, is not in std, imported and not used, main redeclared, the //go:embed refusals, cannot set with -X, misplaced compiler directive — each with its transcript and its fix |
| What vet and gofmt catch | buildtag, directive, stdversion, tests, gofmt on constraint lines, and the longer list of what no tool catches |
| Resources | the go command's documentation by section, release notes by feature, the books' tooling chapters, and what to read with care |
Planned¶
- Cross-compiling with cgo:
GOOS/GOARCHbuilds are shown here only asgo listfile lists; a lesson that builds for another platform and checks the binary withfileneeds an answer key that does not name the platform. - The
tooldirective andgo tool(Go 1.24): a module-versionedstringer, in place of this chapter'sgo run ./gen. - Workspaces,
go.sumandgo mod vendor: whatgo workchanges and what-mod=vendorbuilds from. -gcflagsand-pgo: the compiler's own flags are in The compiler says what it inlines; profile-guided optimisation has no page yet.