makefile-conventions
Skill1 starsChanged 13 days agoMITView on GitHub
Structures Makefiles as a universal command interface using modular includes and self-documenting help. Use when the user wants to add a make target, create a Makefile, organize build commands, set up a make-based workflow, or asks how to structure make targets. Also activate before modifying any Makefile or mk/ file in this project.
In this repository20 other files it gives its agents.
- AGENTS.mdAGENTS.md
- openkata-eval-runnerSkill
- openkata-optimize-skillsSkill
- openkata-review-ruleSkill
- openkata-review-skillSkill
- openkata-rule-conventionsSkill
- openkata-ryu-releaseSkill
- openkata-skill-conventionsSkill
- commit-conventionsSkill
- create-adrSkill
- create-evalsSkill
- create-profileSkill
- create-ruleSkill
- create-skillSkill
- critical-thinkingSkill
- github-create-prSkill
- git-worktreeSkill
- grill-meSkill
- grill-with-docsSkill
- spec-workflowSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 2 are distinctive, and 8 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
Distinctive · estimate
This author's own choices. Worth a look.
8
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 17
Use Make as the universal command interface.
- Very specific: line 37
Add a ## Description comment for the help system
- Very specific: line 39
Use @ prefix for clean output
- Distinctive: line 46
Run the target to confirm it works.
- Very specific: line 84
Never use %: @: catch-all patterns.
- Very specific: line 98
When a domain has 2 or more subcommands, bare make <domain> must show subcommand help.
- Very specific: line 113
When a domain uses $(MAKE) -C for space-separated subcommands (make db migrate), Make sees migrate as a separate goal and errors.
- Very specific: line 136
Never use %: @: — it swallows all unknown targets silently, making typos invisible.
- Very specific: line 144
No existing db.mk — creates mk/db.mk and mk/db/Makefile with migrate, rollback, status
- Distinctive: line 159
Instead, declare valid subcommands explicitly inside conditional blocks.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Makefile Conventions
Use Make as the universal command interface. All project
operations are accessible via make, regardless of the
underlying implementation language.
Workflow
- Investigate the project — Before writing targets, check:
- Does a Makefile already exist? Read it.
- What scripts, tools, or build steps does the project use?
- Is there an existing
mk/directory?
- Decide placement — If the target belongs to an existing concern group, add it there. If it starts a new concern, create a new modular makefile. See makefile-structure for the full modular pattern.
Write the target — Follow these conventions:
- Declare every target
.PHONYunless it produces a file - Add a
## Descriptioncomment for the help system - Delegate complex logic to scripts
- Use
@prefix for clean output - Quote variable references:
"$(VAR)"
- Declare every target
- Update help — Add the new target to the appropriate
concern group in
make helpoutput. - Verify — Run
make helpto confirm the target appears. Run the target to confirm it works.
Complete Example
Root Makefile pattern — includes domain modules and provides grouped help:
.DEFAULT_GOAL := help
include mk/test.mk
include mk/deploy.mk
.PHONY: help
help: ## Show this help
@echo "Project - Make Commands"
@echo "======================"
@echo ""
@echo "Testing:"
@echo " make test - Show test help"
@echo " make test sh - Run shellcheck"
@echo ""
@echo "Development:"
@echo " make check - Check prerequisites"For the full modular delegation pattern (domain .mk
files, subdirectory Makefiles, subcommand delegation), see
makefile-structure.
Conventions
Structure
- One main
Makefileat the project root - Modular makefiles in
mk/for each concern domain - Domains with subcommands get
mk/<domain>/Makefile .DEFAULT_GOAL := helpso baremakeshows help- Never use
%: @:catch-all patterns. Use conditional explicit subcommand declarations instead (see Subcommand Delegation below).
Naming
- Targets: lowercase, hyphenated for multi-word
- Subcommands: space separation (
make test sh) - Variables: UPPER_CASE
Help system
makeormake helpshows all commands grouped by concernmake <domain>shows domain-specific help- When a domain has 2 or more subcommands, bare
make <domain>must show subcommand help. Do not make it execute a default action.
Delegation
Makefiles are the interface, not the implementation:
deploy:
@./scripts/deploy.sh "$(ENV)"Subcommand delegation
When a domain uses $(MAKE) -C for space-separated
subcommands (make db migrate), Make sees migrate as a
separate goal and errors. Solve this with conditional
explicit targets — not a catch-all:
.PHONY: db
db:
@$(MAKE) -C mk/db $(filter-out $@,$(MAKECMDGOALS))
# Only activate when 'db' is on the command line
ifneq ($(filter db,$(MAKECMDGOALS)),)
.PHONY: migrate rollback
migrate rollback:
@:
endifThis ensures:
make db migrate— works (migrate is a known no-op)make db typo— errors (typo has no rule)make typo— errors (conditional is inactive)
Never use %: @: — it swallows all unknown targets
silently, making typos invisible.
Example Scenario
User: "Add a make target for running database migrations"
- Reads existing Makefile — finds
mk/structure - No existing
db.mk— createsmk/db.mkandmk/db/Makefilewithmigrate,rollback,status - Adds
include mk/db.mkto main Makefile - Adds Database section to
make helpoutput - Verifies:
make db migrateworks
Common Failures
- No help text — targets without descriptions are
undiscoverable. Always update
make help. - Logic in Makefiles — complex bash in a target is hard to debug. Delegate to scripts.
- Catch-all swallows errors —
%: @:silently succeeds for ANY unknown target, including typos within domains (make skills typo). Never use a blanket catch-all. Instead, declare valid subcommands explicitly inside conditional blocks.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

