How I stopped worrying and loved Makefiles
Scope of Make: Simple vs Complex Builds
- Many see make as great for simple projects: file-based builds, basic configuration, and lightweight orchestration.
- Once you need feature detection, tool probing, or multi-platform support, the ecosystem tends to push toward GNU make, autotools, CMake, or other heavier systems.
- Several argue that when a Makefile no longer fits on one screen or becomes “clever,” it’s a smell that the build is too complex.
Dependency Management and Cross‑Platform Concerns
- A recurring theme: C/C++ lack a standardized package manager, pushing complexity into build systems.
- Some advocate shipping all dependencies or using language-style package managers; others note that cross-platform libraries and end-user apps often can’t just “ship everything.”
- Containerization (especially Docker) is cited both as a pragmatic workaround for dependency hell and as an unfortunate proliferation of duplicated environments.
- Cross-platform targets (Linux, *BSD, macOS, Windows) complicate matters; make is seen as universal on Unix-like systems but still awkward on Windows.
Make as General Task Runner
- Many use make as a high-level task runner: managing dotfiles, deployments, data processing pipelines, even system startup.
- Defenders say this leverages make’s dependency graph, incremental rebuilds, and parallelism; critics call it an “abuse” and prefer plain shell or custom CLIs.
- There’s agreement that PHONY targets and self-documenting
helppatterns can turn Makefiles into a useful project command menu.
Alternatives to Make
- Popular alternatives for task running include Just, Taskfile, makesure, Rake, and Earthly; Ninja is admired for speed but is intentionally low-level.
- Some feel there’s a niche between make’s complexity and ninja’s minimalism; others see generators (e.g., CMake) as filling that gap, though CMake itself is criticized as slow, opaque, and overfeatured.
- Resistance to new tools often centers on adding yet another dependency versus make’s ubiquity.
Syntax, Ergonomics, and Learning Curve
- Common pain points: tab sensitivity, cryptic automatic variables, legacy built-in rules, tricky variable and environment semantics, and quoting/escaping in recipes.
- Multiple commenters say make became acceptable or even pleasant only after reading the manual or structured tutorials.
- Some prefer CI YAML or dedicated CLIs; others find Makefiles clearer than large YAML pipelines and value decades of battle-tested behavior.
Caching, Correctness, and Security
- There is interest in hash-based caching and better dependency tracking for things like
CPPFLAGS, but consensus that it’s hard to bolt onto make cleanly. - Some argue that language-level package ecosystems are highly exposed to supply-chain attacks; using make with vendored dependencies is viewed as comparatively safer by a few participants.