Makefile design
Skill Amey-Thakur/AI-SKILLS/skills/scripting-automation/makefile-design
Write Makefiles with honest dependencies, phony discipline, and self-documenting help, and know when make is the wrong tool. Use when standardizing project task-running or fixing rebuild bugs.From its SKILL.md
npx -y skills add Amey-Thakur/AI-SKILLS --skill makefile-designAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 24 days oldThe repository was created 24 days ago. New is not bad, but a brand new repository carrying a familiar-sounding name is the shape a typosquat arrives in, and there has been no time for anyone else to find a problem with it.
- 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
3.5 KB, 825 tokens by cl100k_base, as published. Nobody here has run it
Makefile design
Make does two different jobs: incremental file builds (its native
genius) and a task-runner facade (make test, make deploy).
Design differently for each and label which one you are doing.
Method
- State real dependencies for real files. A rule's target and
prerequisites must be actual paths:
dist/app.js: $(SRC) package.json: then make's incremental rebuilds work honestly. Depending on nothing, or on directories (mtimes lie), or on files a recipe does not actually produce breaks the model: stamp files (.build-stamp: deps && touch $@) bridge tools that lack single outputs. - Mark every non-file target .PHONY.
test,lint,clean,deploy: without.PHONY, a file namedtestsilently disables your test target forever. Group the declaration next to each target; a task-runner Makefile is mostly phonies and that is fine: it is the standard entry-point convention teams actually share (see onboarding-docs). - Write recipes that fail loudly and run anywhere. Each recipe
line is its own shell: chain with
&&or use.ONESHELL; setSHELL := bashplus.SHELLFLAGS := -eu -o pipefail -cso failures stop the build (see bash-robustness). Assume nothing about the environment: pin tool invocations through variables (PYTHON ?= python3) so CI and developers override cleanly (see environment-config). - Make help the default target. A
helptarget that greps##comments from targets (test: ## Run the test suite) and prints them; new contributors discover the interface with baremake. This costs six lines and replaces a README section that would rot (see readme-writing). - Use variables and pattern rules before copy-paste.
$(BINARIES): bin/%: cmd/%/main.gocompiles a family from one rule;?=for overridable defaults,:=for computed-once. But stop before make-programming:foreach/evalmetaprogramming is write-only; if the build needs logic, generate the Makefile or move that part to a script the Makefile calls (see bash-robustness step 6). - Choose make deliberately against the alternatives. Make
wins for: file-based incremental steps, ubiquity (preinstalled),
language-agnostic glue as the front door
(
make setup test build) over per-ecosystem runners. It loses for: Windows-native teams (see powershell-essentials), complex DAGs with caching/remote execution (Bazel-class), and pure task-running where ajustfileor package scripts already fit the team. Do not rebuild your language's build system inside make; wrap it (build: ; npm run build) so make stays the thin common interface (see deployment-pipelines for where these targets get called).
Boundaries
- Parallelism (
make -j) is only safe when dependencies are complete and recipes do not share hidden state (temp files, ports); an undeclared dependency that "works" serially corrupts parallel builds (see build reproducibility in artifact-versioning). - Recursive make per subdirectory hides the dependency graph and defeats -j; prefer one top-level Makefile including fragments.
- Tabs-not-spaces and GNU-vs-BSD make differences are real; declare GNU make as the requirement if you use its functions (see shell-portability's declare-your-dialect rule).
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.