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
Xilinx Constraints
Explains Xilinx XDC constraint ordering, compilation precedence, and key references for FPGA timing closure.
Technical Constraints & Requirements
Defines platform, performance, security, and deployment constraints for a Scottish mountain weather app with native iOS/Android and PWA fallback.
Token Constraints Implementation
Defines a token constraint system that counts tokens, truncates content, and streams responses to stay within an LLM's token limit.
Constraints
Explains how to model constraints as Ceres Solver cost functions in the fuse optimization framework, with a complete code example.