Learn Makefiles

GNU Make usage and useful flags

  • Several lesser-known flags are highlighted: output synchronization (--output-sync), load-based parallelism (--load-average), randomizing target order for CI hardening (--shuffle), unconditional rebuilds (-B).
  • Some argue these flags are non‑portable and should be avoided in distributable projects; others respond that the tutorial is clearly about GNU Make and these options are fine for end users and in controlled environments.

Portability vs. GNU extensions

  • One camp stresses portability (POSIX make, portable constructs) as a way to enforce discipline, readability, and maintainability; warns against overusing GNU‑specific metaprogramming features (eval, complex macros).
  • Another camp calls portability overrated, advocating full use of GNU Make’s richer feature set, especially for in‑house or single‑platform projects; notes GNU Make itself is widely portable and commonly available.
  • Some prefer “portable make” (i.e., ship GNU Make everywhere) over writing “portable Makefiles.”

Parallel builds and resource issues

  • Debate over make -j: some consider unbounded -j a footgun causing OOM or I/O storms; others classify that as user error and argue you should always specify reasonable job or load limits.
  • There’s criticism that Make doesn’t provide a “sane” default parallel strategy, leading to unnecessary cognitive load for users.

Appropriate scope and complexity

  • Warnings against turning Make into a Turing‑complete metaprogramming system or reinventing autotools inside Make; implicit rules and default suffix rules are seen as both powerful and dangerous (many serious Makefiles disable them with .SUFFIXES:).
  • Make is praised as a good way to learn declarative thinking, but people caution against using it as a generic task runner for things like Terraform.

Alternatives and modern build tools

  • Many alternatives are mentioned for different niches: Meson, Ninja, CMake, Bazel, xmake, SCons, Task, just, various language‑specific “*-ake” tools, and workflow tools like Snakemake/Nextflow.
  • Some see just/Task as better “command runners” but note they don’t replace Make’s incremental rebuild logic.
  • Others argue modern systems (Bazel, CMake+Ninja, Meson) have largely superseded Make for large C/C++ projects.

C++20 modules and Make

  • C++20 modules are criticized as hard to reason about and implement in traditional build systems; they require dynamic dependency discovery and complicate incremental and parallel builds.
  • Discussion notes that CMake drops Makefile generation for modules in favor of Ninja, but this is attributed more to CMake’s design than an inherent Make limitation.

Tutorial and style feedback

  • Readers appreciate the tutorial as a friendlier on‑ramp than the official manual, but point out technical nitpicks: confusing dependency graphs (source vs binary targets), lack of .PHONY emphasis, recursive make being presented without warning, and some MAKEFLAGS handling being subtly wrong.
  • There’s general agreement that GNU Make’s official manual is high‑quality but dense, and that editor support makes tab‑sensitivity largely a non‑issue.