| I know at least three reasons why makefiles are not working well for common use cases. Many people seem unaware of these cases, even though they seem to come up quite often. • make(1) has a hard time rebuilding target files when source files have changed. The problem is that users have to declare the dependencies of a target before the build, but due to file search paths, it can be that dependencies are only known after building a target. To know about all dependencies, make(1) would have to build any target at least twice. • make(1) by default does not rebuild a target when its build rules change. While this seems really weird to me, it seems to be a consequence of having a single makefile. When a build rule is changed, the makefile changes. So should all targets depend on the makefile implicitly? One could argue that they should – but then each change in a makefile would rebuild all targets. • make(1) can not handle non-existence dependencies. Imagine a file foo.h being searched for by a compiler in directories bar and baz (in that order). If the header file baz/foo.h is found, then bar/foo.h should be considered a non-existence dependency: If at any future point in time it exists, the target should be rebuilt. These problems are all solved by DJB's redo approach, which I implemented in a few hundred lines of Bourne shell (/bin/sh): http://news.dieweltistgarnichtso.net/bin/redo-sh.html |
The compiler may know paths, the linker may know paths, the shell might, make might, or you can supply them.
I've seen and used nested Makefiles before.
These things aren't really make things. If I use tcc, Haskell or Go in my Makefile, then they mightn't apply.
If you can write it in Bash, you can integrate it into your Makefile.