makefile
GNU Make automation and build system guidance. Use when creating or maintaining Makefiles, writing Make targets and recipes, or configuring GNU Make build automation. Keywords: Makefile, GNU Make, targets, recipes, build automation.
What this skill does
# Makefile Skill
Guidance for creating and maintaining GNU Make build automation.
## Quick Navigation
| Topic | Reference |
| ----------------------------- | --------------------------------------- |
| Rules, prerequisites, targets | [syntax.md](references/syntax.md) |
| Variable types and assignment | [variables.md](references/variables.md) |
| Built-in functions | [functions.md](references/functions.md) |
| Special and phony targets | [targets.md](references/targets.md) |
| Recipe execution, parallel | [recipes.md](references/recipes.md) |
| Implicit and pattern rules | [implicit.md](references/implicit.md) |
| Common practical patterns | [patterns.md](references/patterns.md) |
---
## Core Concepts
### Rule Structure
```makefile
target: prerequisites
recipe
```
**Critical:** Recipe lines MUST start with TAB character.
### File vs Phony Targets
```makefile
# File target - creates/updates a file
build/app.o: src/app.c
$(CC) -c $< -o $@
# Phony target - action, not a file
.PHONY: clean test install
clean:
rm -rf build/
```
### Variable Assignment
| Operator | Name | When Expanded |
| -------- | ----------- | ----------------------- |
| `:=` | Simple | Once, at definition |
| `?=` | Conditional | If not already set |
| `=` | Recursive | Each use (late binding) |
| `+=` | Append | Adds to existing value |
```makefile
CC := gcc # Immediate
CFLAGS ?= -O2 # Default, overridable
DEBUG = $(VERBOSE) # Late binding
CFLAGS += -Wall # Append
```
### Automatic Variables
| Variable | Meaning |
| -------- | ------------------------------- |
| `$@` | Target |
| `$<` | First prerequisite |
| `$^` | All prerequisites (unique) |
| `$?` | Prerequisites newer than target |
| `$*` | Stem in pattern rules |
---
## Essential Patterns
### Self-Documenting Help
```makefile
.DEFAULT_GOAL := help
help: ## Show available targets
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf " %-15s %s\n", $$1, $$2}'
install: ## Install dependencies
uv sync
test: ## Run tests
uv run pytest
```
### Platform Detection
```makefile
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Darwin)
OPEN := open
else ifeq ($(UNAME_S),Linux)
OPEN := xdg-open
endif
```
### Build Directory
```makefile
BUILDDIR := build
SOURCES := $(wildcard src/*.c)
OBJECTS := $(patsubst src/%.c,$(BUILDDIR)/%.o,$(SOURCES))
$(BUILDDIR)/%.o: src/%.c | $(BUILDDIR)
$(CC) -c $< -o $@
$(BUILDDIR):
mkdir -p $@
```
### Environment Export
```makefile
export PYTHONPATH := $(PWD)/src
export DATABASE_URL
test:
pytest tests/ # sees exported variables
```
---
## Common Targets
### Quality Checks
```makefile
.PHONY: lint format check test
lint: ## Run linters
ruff check .
mypy src/
format: ## Format code
ruff format .
check: format lint test ## All quality checks
```
### Cleanup
```makefile
.PHONY: clean clean-all
clean: ## Remove build artifacts
rm -rf build/ dist/ *.egg-info
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
clean-all: clean ## Remove all generated files
rm -rf .venv .pytest_cache .mypy_cache
```
### Docker Integration
```makefile
IMAGE := myapp
VERSION := $(shell git describe --tags --always)
docker-build: ## Build Docker image
docker build -t $(IMAGE):$(VERSION) .
docker-run: ## Run container
docker run -d -p 8000:8000 $(IMAGE):$(VERSION)
```
---
## Recipe Execution
### Each Line = Separate Shell
```makefile
# Won't work - cd lost between lines
bad:
cd subdir
pwd # Still in original dir!
# Correct - combine commands
good:
cd subdir && pwd
# Or use line continuation
also-good:
cd subdir && \
pwd && \
make
```
### Silent and Error Handling
```makefile
target:
@echo "@ suppresses command echo"
-rm -f maybe.txt # - ignores errors
```
### Parallel Execution
```bash
make -j4 # 4 parallel jobs
make -j4 lint test # Run lint and test in parallel
```
---
## Output Discipline
**One line in, one line out.** Avoid echo spam.
```makefile
# ❌ Too chatty
start:
@echo "Starting services..."
docker compose up -d
@echo "Waiting..."
@sleep 3
@echo "Done!"
# ✅ Concise
start: ## Start services
@echo "Starting at http://localhost:8000 ..."
@docker compose up -d
@echo "Logs: docker compose logs -f"
```
---
## Conditionals
```makefile
DEBUG ?= 0
ifeq ($(DEBUG),1)
CFLAGS += -g -O0
else
CFLAGS += -O2
endif
ifdef CI
TEST_FLAGS := --ci
endif
```
---
## Including Files
```makefile
# Required include (error if missing)
include config.mk
# Optional include (silent if missing)
-include local.mk
-include .env
```
---
## Common Pitfalls
| Pitfall | Problem | Solution |
| --------------------- | --------------------------------------- | ------------------------ |
| Spaces in recipes | Recipes need TAB | Use actual TAB character |
| Missing .PHONY | `make test` fails if `test` file exists | Declare `.PHONY: test` |
| cd in recipes | Each line is new shell | Use `cd dir && command` |
| `=` vs `:=` confusion | Unexpected late expansion | Use `:=` by default |
| Unexported vars | Subprocesses don't see vars | `export VAR` |
| Complex shell in make | Hard to maintain | Move to external script |
---
## Quick Reference
```makefile
# Makefile Template
.DEFAULT_GOAL := help
SHELL := /bin/bash
.SHELLFLAGS := -ec
.PHONY: help install test lint format clean
help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf " %-15s %s\n", $$1, $$2}'
install: ## Install dependencies
uv sync --extra dev
test: ## Run tests
uv run pytest tests/ -v
lint: ## Run linters
uv run ruff check .
format: ## Format code
uv run ruff format .
clean: ## Clean artifacts
rm -rf build/ dist/ .pytest_cache
```
---
## Links
- [Documentation](https://www.gnu.org/software/make/manual/make.html)
## See Also
- [patterns.md](references/patterns.md) - Extended patterns and recipes
Related in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.