Makefile 不只是编译用的

在项目根目录放一个 Makefile,可以把 pytestruffdocker compose 这类零散命令统一成 make <target>

很多人只在编译项目时见过 make testmake buildmake clean。但 Make 更常见的价值,是把一堆脚本收成可重复执行的工作流。你不需要反复记 python xxx.pybash scripts/deploy.shdocker compose up -d 的细节,只需要记住一个入口:make <target>

先说清楚:Make 是什么

Make 是一个“按目标执行命令”的工具。你先定义目标,比如 testlintrunbackup,再告诉它每个目标该做什么。之后执行时,只要敲:

1
make test

它就会按你写好的步骤运行。

这件事看起来像“给 shell 脚本起别名”,但它至少有两个直接的好处:

  1. 入口统一:团队成员执行同一套命令。
  2. 依赖清楚:一个目标可以依赖另一个目标,不用手工串流程。

最常见的用法:把杂乱命令收口

很多项目的问题不是没有脚本,而是脚本太散。

一个普通项目里,常见动作通常包括:

  • 安装依赖
  • 启动开发环境
  • 跑测试
  • 格式化代码
  • 打包
  • 部署前检查

这些命令往往分散在 README、历史命令和聊天记录里。时间一长,就很容易忘。

这时可以先写一个最小版本的 Makefile:

makefile
.PHONY: install test lint format run

install:
pip install -r requirements.txt

test:
pytest

lint:
ruff check .

format:
ruff format .

run:
python app.py

这里的 .PHONY 可以理解为:这些目标不是文件名,而是动作名。

之后只要记:

1
2
3
make install
make test
make run

比起翻 README 找命令,这种方式更稳定。

再进一步:把流程串起来

Make 的另一层价值,是把动作连成流程。

如果你不想每次发布前都手动回忆“先格式化、再测试、最后打包”,可以直接写成:

makefile
.PHONY: check build release

check: format lint test

build:
python -m build

release: check build
@echo “ready to release”

现在执行:

1
make release

它会先跑 check,而 check 又会依次触发 formatlinttest

这不是复杂技巧,只是把顺序写进文件。以后谁来执行,流程都一致。

关于重复执行:先把边界写清楚

自动化常见的问题不是“写不出来”,而是“第二次运行会不会出问题”。

例如目录已存在、文件重复生成、旧产物没清理、环境状态不一致。Make 本身不能替你解决幂等性,也就是“多跑几次结果是否一致”,但它能促使你把边界写清楚。

例如:

makefile
.PHONY: init clean

init:
mkdir -p data logs tmp

clean:
rm -rf build dist .pytest_cache

这里 mkdir -p 的意思是:目录已存在时不报错。自动化关注的不只是“第一次成功”,还包括“之后还能重复执行”。

如果某个目标会修改状态,名字最好更具体,比如 bootstrapreset-dbseed,不要都叫 run。名字越具体,误操作越少。

Makefile 适合什么,不适合什么

适合的场景:

  • 本地开发命令很多,记不住
  • 想给项目提供统一入口
  • 想把检查、测试、打包串成固定顺序
  • 想让 CI 和本地执行同一套动作

不太适合的场景:

  • 逻辑分支特别复杂
  • 需要大量循环、判断、错误处理
  • 跨平台差异很多,尤其是 shell 行为不一致时

Makefile 更适合做“调度层”,不适合承载太多业务逻辑。复杂逻辑可以放进 scripts/*.shscripts/*.py,Make 只负责调用。

一个常见写法是:

makefile
.PHONY: sync deploy

sync:
bash scripts/sync.sh

deploy:
python scripts/deploy.py

这样 Makefile 更短,脚本也更容易单独测试。

日常任务也可以用 Makefile

即使没有编译需求,也可以给日常任务加一个 Makefile,比如:

makefile
.PHONY: note backup preview

note:
python scripts/new_note.py

backup:
rsync -av ./docs/ /path/to/backup/

preview:
hexo server

之后直接执行:

1
make backup

不必再翻历史记录找备份命令。

这类自动化的价值不在技术炫耀,而在减少重复决策:少记几条命令,少翻一次记录,少跑错一次参数。

一个很实用的下一步

Makefile 的价值还在于可见性。项目根目录放一个 Makefile,别人一打开就能知道这个项目平时怎么运行:make helpmake testmake release

如果准备继续整理工作流,可以加一个 help 目标,把常用命令打印出来。这样比继续堆更多 target 更实用。


Makefile 不只是编译用的
https://ghost.kasumi.live/2026/04/22/Makefile 不只是编译用的/
作者
Amadeus
发布于
2026年4月22日
许可协议