I'd argue it's entirely fair with other examples (e.g. compare and contrast to, say, Rust's cargo build.) You can write a Makefile which fetches and builds your dependencies. Makefiles might be like a recipe - but these days we're building recipes for building entire OS images, including grabbing the dependencies in the first place. A single software project by comparison is trivial.
The problem is Makefiles are a jack of all trades, and master of none. You have to write or copy a distressing number of rules yourself, per project, per subproject, and know the underlying build chain in relative depth to do even some rather basic things. I'd argue makefile authors not automating their dependency fetching is a symptom of this.
As a programmer, I avoid them, because I'll end up stuck maintaining them and end up lowering the build system's bus factor. With perhaps the exception of a couple of simple rules that forward to a "proper" build system, because I've written enough of them in the past that "make" still feels like the right default action that should generally work. But if it all possible, never for the meat of the build system.
Of course. But I would not compare cargo build or CMake to package managers because again, they are developer tools and unless you are a developer you should not need them.
I definitely think that we can do better than Makefiles, but again they have the benefit to be extremely versatile so they can be bent to many uses. (personally I do not use them, I use CMake and generate ninja files)
I'd argue it's entirely fair with other examples (e.g. compare and contrast to, say, Rust's cargo build.) You can write a Makefile which fetches and builds your dependencies. Makefiles might be like a recipe - but these days we're building recipes for building entire OS images, including grabbing the dependencies in the first place. A single software project by comparison is trivial.
The problem is Makefiles are a jack of all trades, and master of none. You have to write or copy a distressing number of rules yourself, per project, per subproject, and know the underlying build chain in relative depth to do even some rather basic things. I'd argue makefile authors not automating their dependency fetching is a symptom of this.
As a programmer, I avoid them, because I'll end up stuck maintaining them and end up lowering the build system's bus factor. With perhaps the exception of a couple of simple rules that forward to a "proper" build system, because I've written enough of them in the past that "make" still feels like the right default action that should generally work. But if it all possible, never for the meat of the build system.