# Go Compiler Flags & Build Configuration Reference

## Build Flags

### Binary Size Reduction

```bash
# Strip symbol table and DWARF debug info (30-40% smaller binary)
go build -ldflags="-s -w" -o app main.go
```

### Build-Time Variable Injection

```bash
# Inject version, commit, build date at link time
go build -ldflags="-X main.version=1.0.0 -X main.commit=$(git rev-parse HEAD)" -o app
```

```go
var version string  // set by -ldflags
var commit string
```

### Debugging Flags

```bash
# Disable optimizations and inlining (for debugger)
go build -gcflags="all=-N -l" -o app main.go
```

### Static Linking

```bash
# Pure Go static binary (no cgo)
CGO_ENABLED=0 go build -o app main.go

# Static with cgo (requires static library versions)
CGO_ENABLED=1 go build -tags netgo \
  -ldflags="-linkmode=external -extldflags '-static'" -o app main.go
```

### Cross-Compilation

```bash
GOOS=linux GOARCH=amd64 go build -o app-linux main.go
GOOS=linux GOARCH=arm64 go build -o app-arm64 main.go
GOOS=darwin GOARCH=arm64 go build -o app-macos main.go
GOOS=windows GOARCH=amd64 go build -o app.exe main.go
```

## Performance-Related gcflags

### Escape Analysis

```bash
# Basic escape info
go build -gcflags='-m' ./...

# Detailed escape reasons (verbose)
go build -gcflags='-m -m' ./...

# Count escapes per file
go build -gcflags='-m' ./... 2>&1 | grep 'escapes to heap' | sed 's/:.*//g' | sort | uniq -c | sort -rn
```

### Inlining Analysis

```bash
# What gets inlined and what can't
go build -gcflags='-m' ./... 2>&1 | grep -E 'inlining|cannot inline'

# Disable inlining (for profiling — see true function costs)
go build -gcflags='-l' ./...
```

### Bounds Check Elimination

```bash
# Show where bounds checks remain
go build -gcflags='-d=ssa/check_bce/debug=1' ./... 2>&1 | grep 'Found'
```

### SSA Debug Output

```bash
# Prove pass (what the compiler proves about bounds, nil checks)
go build -gcflags='-d=ssa/prove/debug=1' ./... 2>&1
```

## Build Tags

### Standard Tags

```go
//go:build linux        // OS-specific
//go:build amd64        // Architecture-specific
//go:build !cgo         // Pure Go fallback
//go:build ignore       // Exclude from compilation
```

### Custom Tags

```go
//go:build debug
package mypackage
// included only with: go build -tags debug
```

### netgo Tag

```bash
# Force pure-Go DNS resolver instead of libc
go build -tags netgo -o app main.go
```

## Runtime Environment Variables

### GC Tuning

| Variable | Default | Effect |
|----------|---------|--------|
| `GOGC=100` | 100 | GC when heap doubles. Higher = less GC, more memory |
| `GOGC=off` | - | Disable GC (batch jobs only) |
| `GOMEMLIMIT=1GiB` | none | Soft memory limit, GC adapts (Go 1.19+) |
| `GODEBUG=gctrace=1` | off | Print GC activity to stderr |

### Scheduler Tuning

| Variable | Default | Effect |
|----------|---------|--------|
| `GOMAXPROCS=N` | CPU count | Max OS threads executing user code |
| `GODEBUG=schedtrace=1000` | off | Print scheduler state every N ms |
| `GODEBUG=scheddetail=1` | off | Detailed per-P/M/G state |

### DNS

| Variable | Effect |
|----------|--------|
| `GODEBUG=netdns=go` | Force pure-Go DNS resolver |
| `GODEBUG=netdns=cgo` | Force cgo DNS resolver |
| `GODEBUG=netdns=2` | DNS debug logging |

## Quick Reference Table

| Flag | Purpose | Example |
|------|---------|---------|
| `-ldflags="-s -w"` | Strip debug info (30-40% smaller) | `go build -ldflags="-s -w"` |
| `-ldflags="-X ..."` | Inject build-time variables | `-X main.version=1.0` |
| `-gcflags='-m'` | Escape analysis | Shows heap escapes |
| `-gcflags='-m -m'` | Verbose escape analysis | Shows escape reasons |
| `-gcflags='-l'` | Disable inlining | For accurate profiling |
| `-gcflags='-N'` | Disable optimizations | For debugging |
| `-gcflags='-d=ssa/check_bce/debug=1'` | Bounds check elimination | Find remaining checks |
| `-tags netgo` | Pure-Go DNS | Static binary |
| `CGO_ENABLED=0` | Disable cgo | Static binary |
| `-race` | Race detector | Mandatory for concurrent code |

## Go Version Build Improvements

| Version | Build Impact |
|---------|-------------|
| Go 1.24 | Swiss Tables hash map (faster runtime internals) |
| Go 1.25 | TLS 1.3 fast path (~58% handshake improvement) |
| Go 1.26 | Small alloc specialization (sub-32-byte), RSA-4096 keygen ~3× faster, `io.ReadAll` ~2× throughput |
