Go Project Makefile with Version Injection

Build a Makefile for Go projects with build, test, lint, version injection via ldflags, cross-compilation, and Docker integration targets.

Language-Specific

Detailed Explanation

Go Project Build Automation

While Go has built-in build tools, a Makefile adds value by standardizing common operations, injecting version information at build time, and providing cross-compilation targets.

Version Injection with ldflags

VERSION := $(shell git describe --tags --always --dirty)
BUILD_TIME := $(shell date -u '+%Y-%m-%d_%H:%M:%S')
LDFLAGS := -ldflags "-X main.version=$(VERSION) -X main.buildTime=$(BUILD_TIME)"

The := operator evaluates the shell commands immediately at parse time. The -ldflags -X flag injects string values into Go variables at link time, embedding version and build information without modifying source code.

Build and Test Targets

.PHONY: build test lint vet

build:
	go build $(LDFLAGS) -o bin/$(BINARY_NAME) ./cmd/...

test:
	go test -v -race -coverprofile=coverage.out ./...

lint:
	golangci-lint run ./...

vet:
	go vet ./...

The -race flag enables the race detector during testing. The ./... pattern tells Go to process all packages recursively.

Cross-Compilation

build-linux:
	GOOS=linux GOARCH=amd64 go build $(LDFLAGS) -o bin/$(BINARY_NAME)-linux-amd64 ./cmd/...

build-darwin:
	GOOS=darwin GOARCH=arm64 go build $(LDFLAGS) -o bin/$(BINARY_NAME)-darwin-arm64 ./cmd/...

build-all: build-linux build-darwin

Go's cross-compilation is controlled by GOOS and GOARCH environment variables, making it trivial to produce binaries for multiple platforms from a single Makefile.

Best Practices

  • Use go mod tidy as a target to keep dependencies clean
  • Include a generate target for go generate ./... if using code generation
  • Add -trimpath to build flags for reproducible builds
  • Use staticcheck or golangci-lint for comprehensive linting

Use Case

Automating the build, test, and release workflow for a Go microservice or CLI tool where you need version stamping, multi-platform binaries, and consistent CI/CD commands.

Try It — Makefile Generator

Open full tool