48 - Build Constraints and Tags
Teaches conditional compilation in Go using build tags, file naming conventions, and the go:generate directive.
What this file does
Teaches conditional compilation in Go using build tags, file naming conventions, and the go:generate directive.
When to use it
- Writing platform-specific code for Linux, macOS, or Windows
- Adding debug-only logging or features to a Go project
- Using custom build tags to toggle optional functionality
- Generating code with go generate in a multi-platform project
Assumes this stack
48 - Build Constraints and Tags
Conditional compilation for different platforms and build configurations.
📌 What You'll Learn
- Build constraints (build tags)
- Platform-specific code
- Custom build tags
- go:generate directive
🔧 Build Constraints
Build constraints = Compile code conditionally
| Use Case | Example |
|---|---|
| Platform-specific | Windows vs Linux |
| Architecture-specific | amd64 vs arm |
| Build modes | debug vs release |
| Optional features | Custom tags |
Two ways to specify:
- File naming:
file_linux.go,file_windows.go,file_darwin.go - //go:build directive:
//go:build linux && amd64
📝 Platform-Specific Code
// main.go - shared code
package main
func main() {
println(getSystemInfo())
}
// system_linux.go
//go:build linux
package main
func getSystemInfo() string { return "Running on Linux" }
// system_darwin.go
//go:build darwin
package main
func getSystemInfo() string { return "Running on macOS" }
// system_windows.go
//go:build windows
package main
func getSystemInfo() string { return "Running on Windows" }
Output: Varies by GOOS build target (e.g., "Running on Linux")
🏷️ Build Tags Syntax
//go:build linux
//go:build linux || darwin
//go:build linux && amd64
//go:build !windows
//go:build (linux || darwin) && amd64
//go:build debug
go build
go build -tags debug
go build -tags "debug integration"
GOOS=linux go build
GOOS=windows GOARCH=amd64 go build
🎭 Debug vs Release
// debug.go
//go:build debug
package main
func debugLog(msg string) { log.Printf("[DEBUG] %s\n", msg) }
const DebugMode = true
// release.go
//go:build !debug
package main
func debugLog(msg string) {}
const DebugMode = false
go build -tags debug -o myapp-debug
go build -o myapp
⚙️ go:generate
//go:generate stringer -type=Status
//go:generate mockgen -source=interface.go -destination=mock_interface.go
go generate ./...
go generate generate.go
📂 File Naming Conventions
| Pattern | Example | When compiled |
|---|---|---|
*_GOOS.go | file_linux.go | Linux only |
*_GOARCH.go | file_amd64.go | amd64 only |
*_GOOS_GOARCH.go | file_linux_amd64.go | Linux amd64 only |
*_test.go | server_test.go | Test build only |
Common values: GOOS: linux, darwin, windows | GOARCH: amd64, arm64, arm, 386
🎯 Key Takeaways
- //go:build for compile-time constraints
- File naming (
_linux.go) for platform code - Custom tags with
-tagsflag - go generate for code generation
- GOOS/GOARCH for cross-compilation
➡️ Next Steps
Next Topic: 49 - Module Management
What's inside
7 sections, 4 code examples, 2 tables, and a syntax reference for build tags.
Change this for your project
- Replace
getSystemInfo()with your own platform-specific function name - Replace
debugLogandDebugModewith your own debug variable and function - Replace
stringer -type=Statuswith your own type name - Replace
mockgen -source=interface.go -destination=mock_interface.gowith your own source and destination paths
Where it goes
Keep it in your repository where the agent or team that needs it will read it.
Worth borrowing
- Use file naming
*_GOOS.goto automatically include platform code without explicit build tags - Pair debug and release files with opposite build constraints to eliminate runtime checks
Related Documents
DunApp PWA - Project Constraints
Defines 14 hard constraints for a Hungarian PWA project, banning Netlify deployment and enforcing local-only testing, Supabase backend, and zero-cost development.
Constraints
Defines a three-tier priority system for design decisions, with conflict resolution examples to guide trade-offs.
Version Constraints Guide
Teaches Composer version constraint syntax for WordPress plugins and themes using a custom shell script wrapper.
Specifying version constraints
Explains how to pin Terraform CLI, provider, and Ansible versions for IBM Cloud Schematics workspaces and actions.