Using Make – writing less Makefile
Programmers revisit the venerable `make` build system, noting how far its implicit rules and minimal Makefiles can be stretched—from tiny C projects to container orchestration and dotfile management. Many praise `make` for its ubiquity, simple dependency tracking, and ability to front-end newer tools like CMake or Ninja, while others argue its arcane syntax, hidden rules, and scaling issues make modern generators or task runners (e.g., CMake, Meson, Ninja, just, Task) more productive. Alongside build-system debates, commenters briefly critique the article’s manpage-style layout for poor readability and accessibility, especially on mobile or with zoom.
Manpage-style presentation & readability
- Several readers like the retro “manpage” aesthetic; others find it hard to read, especially on phones or at high zoom.
- Complaints center on fixed-width, non‑reflowing text and small font sizes; some note this is ironic because real man pages reflow to terminal width.
- Accessibility concerns are raised (vision issues, screen readers). Others argue a personal site can prioritize style over function.
Minimal use of make & implicit rules
- Commenters stress that many examples in the article can be simplified further by relying on built‑in rules:
- If
foo.cexists,make fooworks without a Makefile. - A link rule like
foo: foo.o bar.o baz.ocan often omit the explicit compiler command and just useLDFLAGS/LDLIBS.
- If
- Automatic variables (
$@,$^,$<) are recommended to avoid repeating file lists, though some dislike the “magic” symbols for readability.
Globbing, object lists, and generic Makefiles
- One camp advocates wildcard/globbing for source discovery to avoid ever listing files manually and to enable generic Makefiles reused across many projects and platforms.
- Others warn globbing is:
- Harder to reason about (unintended matches, security/reliability issues).
- Potentially slow on very large trees or when doing recursive scans.
- Problematic for fine‑grained flags and for mapping tidy source trees to out‑of‑tree build directories.
- There’s reference to established multi‑arch patterns where explicit paths are preferred for clarity and control.
Make vs CMake, Meson, Ninja, Autotools, scripts
- Strong disagreement on “make in 2023”:
- Critics call it archaic, verbose, and fragile beyond small projects; prefer CMake/Meson or hand‑rolled builds in Python/Node, citing better ergonomics, dependency discovery, and IDE integration.
- Defenders highlight make’s ubiquity, tiny dependency footprint (good for bootstrapping systems), portability, and decades of stability.
- Ninja is acknowledged as faster on huge builds by dropping expensive make features, but some argue the parsing overhead is negligible for typical projects.
- Autotools is mentioned as powerful but heavyweight; CMake seen as the de facto cross‑platform generator despite its own complexity and debugging pain.
- Some suggest modern tools just re‑learn make’s lessons, slowly accreting similar complexity.
Make as task runner / project front-end
- Many use make primarily as a uniform entrypoint and task runner:
- Targets like
make,make test,make install,make clean,make dev. - Often just call CMake, Cargo, Docker, or language‑specific tools underneath.
- Targets like
- Others argue heavy use of
.PHONYtargets is a smell and recommend tools likejustortaskfor pure command orchestration.
Ergonomics, warts, and usage limits
- Common complaints: tab‑sensitive syntax, implicit rules, whitespace quirks, awkward handling of paths with spaces, and difficulty maintaining large Makefiles.
- Suggested mitigations: keep individual Makefiles small, centralize platform logic in templates, generate dependencies automatically, and use
-j/-lfor parallel builds. - Broad consensus: make is excellent for small to medium, file‑oriented builds and as glue; for large, cross‑platform systems, it often becomes painful and is frequently wrapped or replaced.