All these languages with their half-baked build tools that won't accept that they may have to play nice with other languages and their build tools are not helping.
Of course it is great when you write a language to also throw in a build tool, but in the end if the build tool re-implements 30% or so of make in a broken way I don't see the point.
Make does have its limitations, but most ordinary projects get nowhere close to reaching those.
Well, other build tools sometimes also do a lot more than make ever did. (And in some areas, perhaps less.)
Example: Cabal/cabal-install (for Haskell) can automatically fetch all your project's dependencies and automatically compile them for you.
> Make does have its limitations, but most ordinary projects get nowhere close to reaching those.
I suppose it depends on what you mean by "ordinary", but IME this Makefiles by virtue of being purely file-based is useless for most of my projects. There are a many langauges (e.g. Java/Scala, Haskell) where it just doesn't fit for normal development. As an example: Tracking intra-file dependencies for proper recompilation is really difficult to for Scala code without reimplementing a huge chunk of a Scala compiler. (I'd venture to suggest that you'd be foolish to even try doing this in Make.)
tup (http://gittup.org/tup) has a really nice way of handling interdependencies. They set up some filesystem magic to figure out which files were read while compiling a certain target, and record these files as dependencies for the target.
Another instance of a hard problem ("reimplementing [...] a Scala compiler") that turns into a very easy problem once you look at it from the right angle.
When I decided I needed a single build system to replace a hodgepodge of stuff, I looked at make because that was apparently the go-to thing.
It took me about 2 minutes to decide that I wanted no part of make. I'd assumed it was basically what Tup is. I'm lucky that I learned about Tup from a thread on this site, because it's made me so happy (especially once the initial pain was over... and yeah, you have to change).
So whenever I see these posts, I make sure that someone is mentioning Tup as a clean alternative.
edit: to be explicit, Tup is obsessed with speed and correctness, and handles incremental builds optimally (see Mike Shal's whitepaper on this). The "price" is that you can't modify files during a build. A file is either "regular" (not touched by build) or "generated" (produced wholly from one build rule). You have to describe the complete DAG up front. Because of all this, Tup will actually remove build targets when they're not needed, which I believe no other build system does. I could never go back.
> Another instance of a hard problem ("reimplementing [...] a Scala compiler") that turns into a very easy problem once you look at it from the right angle.
Only if you don't solve the problem fully. TBH, not even zinc solves the problem 100% and sometimes does a little bit of unnecessary re-compilation. It is very good, though.
You need to learn the Make build tool (easy) and then you need to learn bash scripting to get anywhere (argh!).
The OP has linked an example Makefile and I wouldn't be able to maintain/debug it without reading plenty of manpages:
https://github.com/Financial-Times/n-makefile/blob/master/Ma...
Also, a lot of the complexity is due to him being new to make:
asset%:
@if [ -e webpack.config.js ]; then ... fiOne of the normal conventions for Daniel J. Bernstein's tinydns is to use make. No "projects" or "builds" are involved. The goal is not to create a program. Rather, make is used to ensure that the binary form of the DNS database is re-built whenever the system administrator has edited the text form. The administrator simply has to remember to run "make", and the Makefile re-builds, and atomically publishes, the new DNS database.
The simplest makefiles are of the scale exhibited at http://cr.yp.to/djbdns/run-server.html
But one can create significantly more ambitious makefiles than those. (-:
Is make the right tool for executing such tasks? Well, it's not bad for some I guess, and ok if this one project is all you have.
Sometimes you've better off having something that does exactly what you need, regardless of speed. Sometimes you need something fast, lightweight, ubiquitous, and reliable despite its quirks.