I grew frustrated with the compromises of makefiles for this and over the years I wrote a couple of alternatives, run_lib[1] and lk[2]. Now I write files full of the bash functions I need and use lk to explore and execute them. I.e. it's a consistent interface accross projects.
[1] https://github.com/jamescoleuk/lk
[2] https://github.com/jamescoleuk/run_lib