Self-Documenting Makefile with Help Target
Create a self-documenting Makefile with a help target that extracts and displays target descriptions from inline comments using awk.
Detailed Explanation
Self-Documenting Makefiles
A help target that lists all available targets with descriptions makes Makefiles much more user-friendly. This pattern uses special comments and awk to generate formatted help output.
The Comment Convention
.DEFAULT_GOAL := help
build: ## Build the application binary
go build -o bin/app ./cmd/...
test: ## Run all tests with coverage
go test -v -cover ./...
lint: ## Run linters (golangci-lint)
golangci-lint run ./...
clean: ## Remove build artifacts
rm -rf bin/ coverage.out
docker-build: ## Build Docker image
docker build -t myapp .
help: ## Show this help message
@awk 'BEGIN {FS = ":.*##"; printf "Usage:\n make \033[36m<target>\033[0m\n\nTargets:\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 }' $(MAKEFILE_LIST)
How It Works
The awk command:
- Sets the field separator to
:.*##— everything between the colon and## - Matches lines that have a target name followed by
:and then##comment - Prints each target name (in cyan) and its description
$(MAKEFILE_LIST)is a built-in variable containing all included Makefiles
Output
Running make or make help produces:
Usage:
make <target>
Targets:
build Build the application binary
test Run all tests with coverage
lint Run linters (golangci-lint)
clean Remove build artifacts
docker-build Build Docker image
help Show this help message
Setting the Default Goal
.DEFAULT_GOAL := help
This makes help the default target, so running make without arguments shows the help message instead of building something unexpectedly.
Categorized Help (Advanced)
build: ## [Build] Build the application
test: ## [Test] Run unit tests
e2e: ## [Test] Run end-to-end tests
lint: ## [Quality] Run linters
Add category prefixes in brackets and modify the awk script to group targets by category for larger Makefiles.
Use Case
Making a Makefile discoverable for new team members and CI/CD documentation, where running `make` shows all available commands and their descriptions without reading the source file.