
Makefile Review
- 93 installs
- 325 repo stars
- Updated August 2, 2026
- athola/claude-night-market
Review and refactor Makefiles so variables, PHONY targets, help, and pattern rules stay maintainable for repos.
About
Makefile-review is a best-practices module from the Claude Night Market stack that teaches agents how to structure, document, and extend GNU Make build files without common footguns. Solo and indie builders rely on Make when they want one command surface for build, test, and clean across polyglot monorepos or small services. The skill surfaces a canonical file order—project variables first, help as the default goal, explicit .PHONY declarations, and targets annotated with ## so help stays self-updating. It also catalogs pattern rules for format conversion, compiled artifacts, templated JSON configs, and parameterized pytest entry points, plus define blocks for repeating test workflows. Agents use it during review passes when a Makefile grows organically or when onboarding contributors who need predictable targets instead of tribal knowledge. It is guidance and examples, not a linter replacement, so human judgment still applies for platform-specific edge cases.
- Recommended top-to-bottom layout: variables, DEFAULT_GOAL, PHONY, help, then documented main targets
- Self-documenting help target using grep and awk over ## inline comments
- Pattern-rule examples for %.html, object builds, envsubst config templates, and test-% pytest splits
- define/run_tests macro pattern for reusable multi-directory test sequences
Makefile Review by the numbers
- 93 all-time installs (skills.sh)
- Ranked #459 of 1,352 Code Review & Quality skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/athola/claude-night-market --skill makefile-reviewAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 93 |
|---|---|
| repo stars | ★ 325 |
| Security audit | 2 / 3 scanners passed |
| Last updated | August 2, 2026 |
| Repository | athola/claude-night-market ↗ |
What it does
Review and refactor Makefiles so variables, PHONY targets, help, and pattern rules stay maintainable for repos.
Files
Table of Contents
- Quick Start
- When to Use
- Required TodoWrite Items
- Workflow
- Step 1: Map Context (`makefile-review:context-mapped`))
- Step 2: Dependency Graph (`makefile-review:dependency-graph`))
- Step 3: Deduplication Audit (`makefile-review:dedup-candidates`))
- Step 4: Portability Check (`makefile-review:tooling-alignment`))
- Step 5: Evidence Log (`makefile-review:evidence-logged`))
- Progressive Loading
- Output Format
- Summary
- Testing
Testing
Run pytest plugins/pensive/tests/skills/test_makefile_review.py to verify review logic.
Makefile Review Workflow
Audit Makefiles for best practices, deduplication, and portability.
Quick Start
/makefile-reviewWhen To Use
- Makefile changes or additions
- Build system optimization
- Portability improvements
- CI/CD pipeline updates
- Developer experience improvements
When NOT To Use
- Creating new Makefiles - use abstract:make-dogfood
- Architecture review - use architecture-review
Required TodoWrite Items
1. makefile-review:context-mapped 2. makefile-review:dependency-graph 3. makefile-review:dedup-candidates 4. makefile-review:tooling-alignment 5. makefile-review:evidence-logged 6. makefile-review:findings-verified
Workflow
Step 1: Map Context (makefile-review:context-mapped)
Confirm baseline:
pwd && git status -sb && git diff --statVerification: Run git status to confirm working tree state.
Find Make-related files:
rg -n "^include" -g'Makefile*'
rg --files -g '*.mk'Document changed targets, project goals, and tooling requirements.
Step 2: Dependency Graph (makefile-review:dependency-graph)
@include modules/dependency-graph.md
Step 3: Deduplication Audit (makefile-review:dedup-candidates)
@include modules/deduplication-patterns.md
Step 4: Portability Check (makefile-review:tooling-alignment)
@include modules/portability-checks.md
Step 5: Evidence Log (makefile-review:evidence-logged)
Use imbue:proof-of-work to record command outputs with file:line references.
Summarize findings:
- Severity (critical, major, minor)
- Expected impact
- Suggested refactors
- Owners and dates for follow-ups
Progressive Loading
Load additional context as needed:
Best Practices & Examples: @include modules/best-practices.md
Plugin Dogfood Checks: @include modules/plugin-dogfood-checks.md - Makefile completeness analysis, target generation, and dogfooding validation.
Output Format
## Summary
Makefile review findings
## Context
- Files reviewed: [list]
- Targets changed: [list]
## Dependency Analysis
[graph and issues]
## Duplication Candidates
### [D1] Repeated command
- Locations: [list]
- Anchor: `verbatim source text at file:line`
- Recommendation: [pattern rule]
## Portability Issues
[cross-platform concerns]
## Missing Targets
- [ ] help
- [ ] format
- [ ] lint
## Recommendation
Approve / Approve with actions / BlockVerify Findings Are Grounded (makefile-review:findings-verified)
Every finding must cite a real location and a verbatim anchor. Write findings to .review/findings.json and confirm each citation resolves:
python plugins/imbue/scripts/citation_verifier.py \
--findings .review/findings.json --repo-root .Drop or label UNVERIFIED any finding the verifier fails (exit 1); only verified findings enter the report. See Skill(imbue:review-core) Step 5 and Skill(imbue:structured-output) for the schema.
Exit Criteria
- Context mapped
- Dependencies analyzed
- Deduplication reviewed
- Portability checked
- Evidence logged
- Every reported finding carries a
Location+ verbatimAnchorconfirmed
by citation_verifier.py (exit 0), or unverified findings were dropped or labeled UNVERIFIED
Troubleshooting
Common Issues
No Makefile found Ensure Makefile or *.mk files exist in the project root or specify paths explicitly.
Include directives not resolved Run rg -n "^include" -g'Makefile*' to trace include chains manually.
Makefile Best Practices
Structure Pattern
Recommended organization:
# 1. Variables at top
PROJECT := myproject
SRC_DIR := src
BUILD_DIR := build
VERSION := 1.0.0
# 2. Default goal
.DEFAULT_GOAL := help
# 3. PHONY declarations
.PHONY: all build test clean help
# 4. Help target (self-documenting)
help: ## Show this help
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
awk 'BEGIN {FS = ":.*?## "}; {printf "%-15s %s\n", $$1, $$2}'
# 5. Main targets with inline docs
build: ## Build the project
$(MAKE) -C $(SRC_DIR)
test: build ## Run tests
pytest tests/
clean: ## Clean build artifacts
rm -rf $(BUILD_DIR)Pattern Rule Examples
File Conversion
# Markdown to HTML
%.html: %.md
pandoc $< -o $@
# Source to object
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
@mkdir -p $(@D)
$(CC) $(CFLAGS) -c $< -o $@
# Template expansion
%/config.json: templates/config.json.tmpl
@mkdir -p $(@D)
envsubst < $< > $@Testing Patterns
# Test by subdirectory
test-%:
pytest tests/$*
# Test by type
test-unit test-integration test-e2e: test-%:
pytest tests/$* -vFunction Examples
Reusable Command Sequences
define run_tests
@echo "Testing $(1)..."
cd $(1) && pytest -v
@echo "Done: $(1)"
endef
test-all:
$(call run_tests,module1)
$(call run_tests,module2)Multi-line Recipes
define docker_build
docker build \
--build-arg VERSION=$(VERSION) \
--tag $(1):$(VERSION) \
--tag $(1):latest \
.
endef
image:
$(call docker_build,$(PROJECT))Anti-Patterns to Avoid
Repeated Commands
# Bad - duplicated logic
test-unit:
pytest tests/unit
test-integration:
pytest tests/integration
# Good - pattern rule
test-%:
pytest tests/$*Missing PHONY
# Bad - 'clean' file blocks target
clean:
rm -rf build/
# Good
.PHONY: clean
clean:
rm -rf build/Hardcoded Paths
# Bad - not portable
clean:
rm -rf /home/user/project/build
# Good - variables
BUILD_DIR ?= build
clean:
rm -rf $(BUILD_DIR)Shell-Specific Commands
# Bad - Bash-only
check:
[[ -f config.yaml ]] && echo "Found"
# Good - POSIX compatible
check:
[ -f config.yaml ] && echo "Found"Unguarded Variable References
# Bad - fails if undefined
clean:
rm -rf $(BUILD_DIR)
# Good - with default
BUILD_DIR ?= build
clean:
rm -rf $(BUILD_DIR)Non-Idempotent Targets
# Bad - appends every time
configure:
echo "DEBUG=1" >> config.mk
# Good - idempotent
configure:
@echo "DEBUG=1" > config.mkError Handling
Check Prerequisites
.PHONY: check-deps
check-deps:
@command -v python3 >/dev/null || (echo "python3 required"; exit 1)
@command -v pytest >/dev/null || (echo "pytest required"; exit 1)
test: check-deps
pytest tests/Delete on Error
# Automatically delete targets on error
.DELETE_ON_ERROR:
build/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@Pipeline Exit Code Propagation
# Bad - pipeline exit code is from grep, not make
check:
@$(MAKE) typecheck 2>&1 | grep -v "^make\["
# Good - capture exit code explicitly in wrapper scripts
# See shell-review skill for bash pipeline patterns
check:
@$(MAKE) typecheck || { echo "Type check failed"; exit 1; }
# Good - use .SHELLFLAGS for pipefail in recipes
SHELL := /bin/bash
.SHELLFLAGS := -eu -o pipefail -cWhen recipes use pipelines, ensure exit codes propagate correctly. In bash, the default behavior is that pipeline exit code equals the last command's exit code. Use set -o pipefail or capture output and exit codes separately.
Parallel Execution
# Enable parallel by default
MAKEFLAGS += -j$(shell nproc 2>/dev/null || echo 1)
# Or disable for specific targets
.NOTPARALLEL: install deployDeduplication Patterns
Recipe Duplication Detection
Search for repeated command patterns:
# Common test commands
rg -n "cargo test" -g'Makefile*'
rg -n "pytest" -g'Makefile*'
rg -n "npm run" -g'Makefile*'
rg -n "go test" -g'Makefile*'
# Build commands
rg -n "docker build" -g'Makefile*'
rg -n "gcc.*-o" -g'Makefile*'Pattern Rules
Replace repeated rules with patterns:
# Bad - repeated
test-unit:
pytest tests/unit
test-integration:
pytest tests/integration
test-e2e:
pytest tests/e2e
# Good - pattern rule
test-%:
pytest tests/$*Pattern rule for file conversion:
# Convert all .md to .html
%.html: %.md
pandoc $< -o $@
# Build objects from sources
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) $(CFLAGS) -c $< -o $@Static Pattern Rules
For specific targets with patterns:
SOURCES := foo.c bar.c baz.c
OBJECTS := $(SOURCES:.c=.o)
$(OBJECTS): %.o: %.c
$(CC) $(CFLAGS) -c $< -o $@Functions and Define Blocks
Reusable command sequences:
# Define reusable function
define run_tests
@echo "Testing $(1)..."
cd $(1) && pytest
endef
test-all:
$(call run_tests,module1)
$(call run_tests,module2)Multi-line define blocks:
define install_package
@echo "Installing $(1)..."
pip install --quiet $(1)
@echo "Done: $(1)"
endef
deps:
$(call install_package,pytest)
$(call install_package,black)Automatic Variables Reference
Use automatic variables to reduce duplication:
| Variable | Meaning | Use Case |
|---|---|---|
$@ | Target name | Output file path |
$< | First prerequisite | Main input file |
$^ | All prerequisites | Link all objects |
$? | Newer prerequisites | Incremental builds |
$* | Stem match | Pattern rule matching |
$(@D) | Directory of target | mkdir parent |
$(<D) | Directory of first prerequisite | Source dirs |
Example:
# Before
build/foo.o: src/foo.c
$(CC) $(CFLAGS) -c src/foo.c -o build/foo.o
# After
build/%.o: src/%.c
$(CC) $(CFLAGS) -c $< -o $@Clean Target Best Practices
# Good - use variables, don't duplicate paths
BUILD_DIR ?= build
DIST_DIR ?= dist
.PHONY: clean distclean
clean:
rm -rf $(BUILD_DIR)
distclean: clean
rm -rf $(DIST_DIR)Dependency Graph Analysis
Make Database Inspection
Inspect the complete expanded database:
make -pn | lessThis shows:
- All rules (implicit and explicit)
- Variable assignments
- Default values
- Pattern rules
PHONY Detection
Check for .PHONY declarations:
rg -n "^\.PHONY:" -g'Makefile*'Common PHONY targets that should be declared:
all,build,test,clean,installhelp,format,lint,releasedistclean,check,docs
Circular Dependency Checks
Look for circular dependencies:
make -pn 2>&1 | grep -i "circular"Common patterns:
# Bad - circular
A: B
B: A
# Good - linear
A: B
B: CInclude File Patterns
Find include directives:
rg -n "^include|^-include" -g'Makefile*'Check for:
- Redundant includes
- Missing includes
- Include order issues
- Conditional includes
Validate included files exist:
# List includes
rg "^include\s+(\S+)" -or '$1' -g'Makefile*'
# Check they exist
for f in $(rg "^include\s+(\S+)" -or '$1' -g'Makefile*'); do
[ -f "$f" ] || echo "Missing: $f"
donePlugin Dogfood Checks
Analyzes Makefiles to identify gaps in user-facing functionality, safely tests existing targets, and generates missing targets with contextually appropriate templates.
Overview
This module provides detailed Makefile analysis and enhancement for the claude-night-market project. It validates that all plugins have complete, consistent, and functional Makefile targets that support common user workflows.
Workflow
1. Discovery Phase
makefile_dogfooder.py --scope all --mode analyzeThe discovery phase:
- Recursively searches for Makefile, makefile, GNUmakefile, and *.mk files
- Parses target definitions with dependencies and commands
- Extracts variable assignments and include statements
- Builds dependency graphs and detects plugin type (leaf vs aggregator)
2. Analysis Phase
makefile_dogfooder.py --mode analyze --output jsonThe analysis phase evaluates:
- Essential targets (help, clean, .PHONY) - 20 points each
- Recommended targets (test, lint, format, install, status) - 10 points each
- Convenience targets (demo, dogfood, check, quick-run) - 5 points each
- Anti-patterns (missing .PHONY, no error handling)
- Consistency across multiple Makefiles
3. Testing Phase
makefile_dogfooder.py --mode testThe testing phase performs:
- Syntax validation with
make -n - Help target functionality checks
- Variable dependency verification
- Common runtime issue detection
4. Generation Phase
makefile_dogfooder.py --mode full --applyThe generation phase creates:
- Demo targets to show plugin functionality
- Dogfood targets for self-testing
- Quick-run targets for common workflows
- Check-all targets for aggregator Makefiles
Best Practices
For Leaf Plugins
- Always include: help, clean, test, lint
- Add demo target to show functionality
- Include dogfood target for self-testing
- Use shared includes from abstract when possible
For Aggregator Makefiles
- Delegate to plugin Makefiles with pattern targets
- Include check-all target for detailed validation
- Maintain consistent target naming across plugins
- Provide helpful aggregate status information
Target Naming
- Use kebab-case for target names
- Include brief description with
##comment - Group related targets with prefixes (test-, dev-, docs-)
- Follow alphabetical ordering for readability
Demo Target Philosophy
Demo targets must run ACTUAL functionality, not just echo static information.
| BAD (Static/Informational) | GOOD (Live/Functional) |
|---|---|
@echo "Skills: 5" | $(UV_RUN) python scripts/validator.py --scan |
| `@find skills/ \ | wc -l` |
@echo "Feature: validation" | $(UV_RUN) python scripts/validator.py --target . |
Integration
With Slash Commands
/make-dogfood --scope plugins --mode fullWith CI/CD
- name: Validate Makefiles
run: makefile_dogfooder.py --mode test --output jsonScoring
Each Makefile is scored 0-100 based on target coverage:
- Essential targets: 20 points each
- Recommended targets: 10 points each
- Convenience targets: 5 points each
- Anti-pattern penalties: -5 to -10 each
Portability Checks
GNU Make Features
Check for GNU-specific features that may not be portable:
Advanced Directives
rg -n "^\\.ONESHELL:" -g'Makefile*'
rg -n "^\\.NOTPARALLEL:" -g'Makefile*'
rg -n "^\\.DELETE_ON_ERROR:" -g'Makefile*'.ONESHELL- Single shell per recipe (GNU Make 3.82+).NOTPARALLEL- Disable parallel execution.DELETE_ON_ERROR- Delete targets on error
Order-Only Prerequisites
rg -n "\|[^|]" -g'Makefile*'Order-only prerequisites (target: normal | order-only) are GNU Make only.
GNU Functions
rg -n "\$\(shell " -g'Makefile*'
rg -n "\$\(wildcard " -g'Makefile*'
rg -n "\$\(foreach " -g'Makefile*'
rg -n "\$\(eval " -g'Makefile*'Common GNU functions:
$(shell ...)- Execute shell command$(wildcard pattern)- File globbing$(foreach var,list,text)- Loop$(eval text)- Dynamic evaluation
POSIX Compatibility
For maximum portability:
# POSIX-compatible shell
SHELL := /bin/sh
# Avoid Bash-specific features
# - Arrays: arr=(1 2 3)
# - [[ ]]: use [ ] instead
# - Process substitution: <(cmd)
# - Brace expansion: {1..10}Shell Configuration
Good: POSIX Compatible
SHELL := /bin/shIf Bash Required
Document and configure properly:
# Requires Bash 4.0+
SHELL := /bin/bash
.SHELLFLAGS := -eu -o pipefail -c
# -e: exit on error
# -u: error on undefined variable
# -o pipefail: pipe fails if any command fails
# -c: execute commandCross-Platform Safety
Path Separators
# Good - portable
SRC_DIR := src
BUILD_DIR := build
# Bad - hardcoded separator
SRC_DIR := src/main/resourcesCommand Portability
# Check for required commands
ifeq ($(shell command -v pandoc 2>/dev/null),)
$(error pandoc is required but not installed)
endifPlatform Detection
UNAME := $(shell uname -s)
ifeq ($(UNAME),Linux)
# Linux-specific
endif
ifeq ($(UNAME),Darwin)
# macOS-specific
endifQuality Gate Targets
validate standard targets exist:
rg -n "^help:" -g'Makefile*'
rg -n "^format:" -g'Makefile*'
rg -n "^lint:" -g'Makefile*'
rg -n "^test:" -g'Makefile*'
rg -n "^build:" -g'Makefile*'
rg -n "^clean:" -g'Makefile*'Recommended targets:
help- Show available targetsformat- Code formattinglint- Linting checkstest- Run test suitebuild- Build artifactsclean- Clean build artifactsrelease- Production buildinstall- Install artifacts
Related skills
FAQ
Is Makefile Review safe to install?
skills.sh reports 2 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.