一键导入
mk
Makefiles. NOT for shell scripts (use sh) or build configs (use language skill).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Makefiles. NOT for shell scripts (use sh) or build configs (use language skill).
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Development wisdom and workflow rules. NOT for project-specific conventions (those live in CLAUDE.md, edit via wisdom).
The `BUGS.md` open-issues queue — entry format, lifecycle, pruning to diary. NOT for the record-don't-fix policy (that's CLAUDE.md Bug Triage Protocol), NOT for resolved-bug history (use /diary), NOT for feature backlog (use TODO.md/specs).
Terminal demo GIF + MP4 recordings for READMEs and social (asciinema + agg + ffmpeg). NOT for general Makefile targets (use software) or GUI screenshots (use visual).
Go development. NOT for non-Go code (use rs, py, ts, tsx, or sh).
Humanize text: strip AI-isms and add real voice. NOT for drafting new copy (use writing).
Python development. NOT for shell scripting (use sh) or non-Python code.
| name | mk |
| description | Makefiles. NOT for shell scripts (use sh) or build configs (use language skill). |
| when_to_use | editing Makefile, writing make targets, tool download targets, pattern rules |
| user-invocable | false |
ALWAYS read the software baseline (software/code.md) first for shared naming,
style, and design rules. Below are Make-specific additions.
Make has its own escaping rules ($$ for shell $, $$$$ inside define), its own
expansion phases (immediate vs deferred), and its own caching model (file mtime vs
.PHONY). Each layer of indirection (macros, eval, computed targets) interacts with
those rules and turns into hard-to-read symbols.
Repeat yourself before reaching for indirection. Three near-identical 4-line recipes are clearer than one 4-line macro called three times.
Direct rule of thumb: if the indirection requires $$$$ to work, it's too clever.
This is the idiomatic Make answer. Each target carries its own URL, SHA, EXTRACT command via target-specific variables. A single recipe consumes them.
$(TOOL_A): URL := https://example.com/a.tgz
$(TOOL_A): SHA := abc123...
$(TOOL_A): EXTRACT = tar -xzf "$$t" -C $(CURDIR)/.hooks a
$(TOOL_B): URL := https://example.com/b.tgz
$(TOOL_B): SHA := def456...
$(TOOL_B): EXTRACT = tar -xzf "$$t" -C $(CURDIR)/.hooks --strip-components=1 b
$(TOOLS):
@t=$$(mktemp); curl -sL "$(URL)" -o "$$t"; \
echo "$(SHA) $$t" | sha256sum -c --quiet; \
$(EXTRACT); rm -f "$$t"
NOT this:
define DOWNLOAD
@t=$$$$(mktemp); curl -sL "$(1)" -o "$$$$t"; ...
endef
$(TOOL_A): ; $(call DOWNLOAD,https://...,abc...,...)
$$$$ is the giveaway — you've gone too far.
:= immediate expansion — default choice. Value frozen when the line is read.= recursive — defer expansion until the variable is used. Use when value contains
$$t or other shell vars that must survive into the recipe unexpanded.:= and = across per-target vars is fine and expected.sha256sum -c --quiet before extracting..hooks/kustomize), never .PHONY. Make's file-mtime
cache then naturally skips re-downloads.| Target | Purpose |
|---|---|
prepare | Install all deps (dev + runtime) |
check | Lint + format check (ruff or equivalent) |
right | Type check (pyright or equivalent) |
test | Fast unit tests |
integration | Integration / e2e tests |
clean | Remove build artifacts |
CI pipelines call these targets by name — keep them consistent across components.
help, lint, test, install, clean, etc..PHONY a target that produces a file on disk. It defeats caching.The help target uses @echo " target description" with aligned
double-quoted strings. NEVER regex-collapse multiple spaces in Makefiles
— re.sub(r' +', ' ', ...) or equivalent will silently destroy this
alignment. When removing a target, delete only its lines; never post-process
the whole file.
help:
@echo "Usage:"
@echo " prepare installs dependencies"
@echo " right type check (pyright)"
@echo " test fast unit tests"
Double quotes in @echo "..." are correct Make syntax — do NOT convert them
to single quotes (yamlfmt single-quote convention applies only to .yml files).
$$ to escape $ for the shell. $$(mktemp) becomes $(mktemp) in shell.\ line continuations with ; between commands. Each unjoined line runs in its
own shell — variables don't carry across.@ prefix suppresses echo. Use sparingly; usually you want to see what ran.