The trouble with "make" is that it's supposed to be driven by dependencies, but in practice it's used as a scripting language. If the dependency stuff worked, you would never need
make clean; make
or touch
Yeah this is my pet peeve about how people use Makefiles. Make is supposed to be a dependency-driven "dataflow" language, but over time it's evolved into something like shell. And people tend to use it like shell.
The most glaring example is .PHONY targets, which are a hack and should just be shell functions. In 'make ', should be data, not code. 'make test' doesn't make sense, but 'make bin/myprog' does.
I posted this link in another comment showing how Make, Shell, and Awk overlap:
http://www.oilshell.org/blog/2016/11/14.html
Here are some more comments on Make's confused execution model. It's sort of functional/dataflow and sort of not. In practice you end up "stepping through" an imperative program rather than reasoning about inputs and outputs like in a functional program.
https://news.ycombinator.com/item?id=14840696
And at the end of this post, I talk a bit more about the functional model:
What simple tool would you suggest to address those .PHONY-targets instead of a Makefile?
So instead of 'make test', I just use './test.sh all', or './test.sh foo'. The test script can invoke make.
The idea is that 'dataflow' parts are done in Make, and the imperative parts are done in shell. This works out fairly well if you're disciplined about it. The only point of Makefiles is to support quick incremental builds. If there's no incrementality, then you might as well use shell. (Note: whenever you use Make, you're using shell by definition. There's no possibility of only using Make. So I take Make out of the picture where it's not necessary.)
For example, all the instructions here are of the form 'foo.sh ACTION':
https://github.com/oilshell/oil/wiki/Contributing
Pretty much every shell script in the repo uses "the argv dispatch pattern"... I've been meaning to write a blog post about that pattern, i.e. using functions with the last line as "$@".