编程与软件工程tech.davis-hansson.com
GNU Make 的实用主义指南
An opinionated approach to GNU Make
2019 — 2022,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这是一篇关于 GNU Make 的观点性指南,作者主张把 Makefile 当作“文件生成器”来用:用真实文件(如 sentinel 文件)作为目标,而不是依赖 .PHONY;显式写出 $@、$< 这类魔法变量;并为更可读的写法给出了一系列个人化建议,包括用 .RECIPEPREFIX = > 把 recipe 前缀从 Tab 换成 >,以及设置 SHELL := bash 并启用严格模式。评论区的讨论相当两极:有人分享了自己的实用技巧,也有人认为替换 Tab、强制 bash 和照搬 strict mode 会让 Makefile 变得不兼容,或让人难以理解。
为什么经久不衰:Make 至今仍是 Unix 世界通用的构建工具,这篇文章把常见痛点浓缩成具体可操作的写法;而评论中的反驳同样有价值,能帮助读者判断哪些建议适合放进自己的项目。
HN 评论精选
补充两个实用简写技巧,并推荐自己更进阶的 GNU Make 资料。
单行 recipe 可以用分号写:foo.o: foo.c ; $(CC) $<。如果觉得 $(@D) 不好记,可以用 $(dir $@) 代替。我写过一本关于 GNU Make 的书;只有当(且仅当)你读过 FSF 的 GNU Make 手册之后,我的书才可能帮到你,它不是给新手看的。不想要书的话,文章都在这里。
jgrahamc查看英文原文
For one-line recipes you can use semicolon foo.o: foo.c ; $(CC) $< If you find $(@D) hard to remember then do $(dir $@) instead. I wrote a book about GNU Make stuff (https://nostarch.com/gnumake). If (and only if) you've read the GNU Make Manual from the FSF my book may help you. It's not for newbies. Don't want the book? All the articles are here: https://blog.jgc.org/2013/02/updated-list-of-my-gnu-make-articles.html
分享用 awk 加特殊注释自动生成 make help 的自我文档化技巧。
学到了一些好技巧。有一个我常用但文章里没提到:用 awk、`## 说明` 注释和 `.DEFAULT_GOAL := help`,可以让 Makefile 具备一定自我文档化能力。运行 make(或 make help)就能列出所有已文档化的任务,非常好用。
cies查看英文原文
Learned some good tricks here. There's one that I use but did not find in the article. This one: # Borrowed from https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html .PHONY: help help: ## Display this help section @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z0-9_-]+:.*?## / {printf "\033[36m%-38s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) .DEFAULT_GOAL := help .PHONY: load-terraform-output load-terraform-output: ## Request the output JSON from Terraform some commands some more It makes Makefiles a little more self documenting. Now I issue a `make` (or `make help`) to get a listing of the documented tasks. Very helpful.
赞同把 make 当文件生成工具,但认为替换 Tab 的建议很傻,且文章漏了 % 模式匹配这一关键机制。
我喜欢其中一部分!Tab 与空格那段我觉得挺傻的:如果你的编辑器会随机把 Tab 和空格互换,那就换个更好的编辑器;Makefile 默认就用 Tab,这没问题。用 `> ` 代替 Tab 只会显得更杂乱。关于文件系统的观察很好,希望它广为人知:应该把 Makefile 当作生成文件的工具,它非常偏向这个用途,而不是通用脚本语言。我倒是想知道作者能否把测试组织成真正生成输出文件、让 make 追踪,也让测试追踪依赖。关于魔法变量的说法我认同,它们有时确实晦涩(虽然很容易查)。不过我觉得他漏了 % 模式匹配:如果 make 不能帮你生成至少一部分 recipe,那为什么不直接写个 build.sh?
bee_rider查看英文原文
I like parts of it! The tabs vs spaces thing seems pretty silly to me. If your editor is randomly swapping tabs and spaces, get a better editor. Tab is the default in a makefile and that seems fine. The suggestion to use "> " instead of tab just looks noisier. The observation about the filesystem is good and hopefully well known. The way to think about makefiles is as a tool for creating files (it is very oriented toward this), not as a general purpose scripting language (it is just a worse version of whatever scripting language you are in it, if you use it this way). I do wonder if he could structure his tests to have them actually generate output files which make could track, and also have his tests track dependencies. Point taken about the magic variables. Sometimes they can get obscure (although they are pretty easy to look up). IMO one he's missing, though, is the pattern matching % operator. If make isn't generating at least some of your recipes for you, then why not just make a "build.sh" script?
批评 `SHELL := bash` 与 `-eu -o pipefail` 是在照搬严格模式,会带来性能与行为一致性问题,并非好默认。
这篇文章有些建议我认为有问题。`SHELL := bash`:bash 比 dash 慢得多,所以 Debian 等发行版不用它作 /bin/sh。.ONESHELL 能缓解速度问题,但也可以直接用默认 shell 而不开 ONESHELL。关于 bash 严格模式和 `.SHELLFLAGS := -eu -o pipefail -c`:希望大家别再照搬所谓的 strict mode。`-e` 之所以有用,只是因为作者喜欢 ONESHELL;关掉 ONESHELL 就不需要它。`-u` 有时有用,取决于风格:我在复杂脚本里用,但单个 Makefile recipe 未必需要那么复杂,而且 `-u` 会让 shell 的变量处理行为与 make 不一致。`pipefail` 是 bash 特有的;只有把 SHELL 设成 bash 才有效。我也不认为它是个好默认值,有时有用,有时恰恰相反,取决于你写的管道。
nrclark查看英文原文
This article has some questionable advice imo. SHELL := bash Bash is a much slower shell than Dash, which is why Debian and friends don't use it as /bin/sh. .ONESHELL mitigates the speed problem, but you could also just use the default shell and leave ONESHELL turned off. Use bash strict mode .... .SHELLFLAGS := -eu -o pipefail -c I wish people would stop cargo-culting the so-called "strict mode". The -e flag is only useful because the author likes .ONESHELL mode. If you leave ONESHELL turned off, then you don't need it. The -u flag is useful sometimes, depending on coding style. I use it on complex scripts. Individual Makefile recipes maybe don't want that much complexity though. Also the -u flag makes the shell's variable-handling behavior inconsistent with Make's. The pipefail option is Bash-specific, and only works because the author likes to set SHELL to Bash in their Makefiles. It's also not a good default in my opinion. There are times when it's useful, and other times when it's the opposite of what you want. Just depends on the pipeline that you're writing.
历次讨论
同类还值得读
开源应用架构
The Architecture of Open Source Applications
《开源软件架构》(AOSA)是一本在线免费书,邀请知名开源项目的作者亲自剖析其内部设计,涵盖 SQLAlchemy、LLVM、Audacity、Apache、Bash 等系统。
编程与软件工程上首页 9 次 · 2011–2024aosabook.org编辑精选编程语言简史:简短、不完整且多半错误
A Brief, Incomplete, and Mostly Wrong History of Programming Languages
一篇以戏谑、故意不准确的方式回顾编程语言史的博客文章,用夸张轶事和讽刺定义串起 Lisp、C、C++、Java、JavaScript、PHP 等语言。
编程与软件工程上首页 8 次 · 2009–2021james-iry.blogspot.comSQLite 是如何测试的
How SQLite is tested
SQLite 官方文档页,系统介绍 SQLite 的测试体系:多种测试方法(TCL 测试、模糊测试、回归测试、静态分析等)和海量测试用例,展示了这个小型开源项目如何靠极致测试获得…
编程与软件工程上首页 8 次 · 2009–2025sqlite.org编辑精选高级编程语言(2009)
Advanced programming languages (2009)
Matt Might 的经典文章,按用途推荐“高级编程语言”:如果追求就业就选主流语言,如果追求表达力、学术研究或创业,则推荐 Haskell、OCaml、Scala 等函数式语…
编程与软件工程上首页 8 次 · 2009–2022matt.might.net我的 Forth 与栈机器经历
Yosefk - My history with Forth & stack machines
作者以亲身经历回顾了使用 Forth 语言和栈式机器的历程:既赞叹其简洁优雅、代码量小、可自举的优点,也坦率指出栈操作在实际编程中的痛苦,以及 Forth 社区文化中的问题。
编程与软件工程上首页 8 次 · 2010–2024yosefk.com编辑精选