I'd love to look into a parallel universe where Make didn't make so many really basic mistakes by 2023 standards. For instance, it has a lot of the "was there an error? eh, just keep going" philosophy from early days. I'd like it to be an error if a make rule claims to make a certain dependency and it fails to do so. That one change in a single stroke would eliminate a lot of Make's hostility when trying to first understand it. There's a series of similar things that could be done.
All of its replacements generally involve such a paradigm shift that it's no longer a comparable, to use a real estate term.
I've got a whole list; $ being used for both make and shell replacements, leading to $$$$(var) abominations and the general lack of clarity as to which variables are for which things, many places where lists were clearly bodged in as after thoughts when they should be designed in from the beginning, tabs as meaningful whitespace is a classic but still a problem, .PHONY being a rather ugly hack when there should be a clear distinction between "a command I want to provide" versus "this is how to make a dependency", and while this may not be a user-visible behavior change, taking away all the C defaults so the strace is no longer a nightmare of trying every implicit C rule before actually trying the rule I want it to try. At least a mode of invoking the shell that looks more like a programming language where I pass a clean array of strings rather than the shell language, already a nightmare of string interpolation on its own terms, buried in another string interpolation language sitting on top of it. A thought-out solution to recursive versus included makefiles. And I never became a make master, but by my 21st century standards, trying to use make is just a fractal of bad 1970s ideas hitting me at every turn, so I'm quite sure if I had to work with it a lot more I could go on for quite a while. As it is I think I've forgotten some.
I think people, not entirely illegitimately, have trouble separating the essential concept of make, which I think was quite solid, from the accidental comedy of errors that we have as a received standard. So a lot of make replacements end up running from both of them, and often end up with a much more annoying essential concept at their core, such as a super-heavy-duty enumeration of "these are the exact things you may ever be interested in doing", which puts them behind the eight ball no matter how good their accidental choices may be.
> For instance, it has a lot of the "was there an error? eh, just keep going" philosophy from early days.
I don't know what you're talking about. make stops when a command it has launched terminates with a non-zero exit code, and if anything, "just keep going" is rather a thing in today's needlessly-async JavaScript tool chains.
Well, I'd be talking about things like "I'd like it to be an error if a make rule claims to make a certain dependency and it fails to do so.", like I said in the next sentence.
While we're at it, undefined variables should be errors, not turned into empty strings, and like I said, were I working with it routinely I'm sure I could come up with more. There's a lot more to make than just its shell invocations.
Furthermore, embedding shell's default error handling behavior into make isn't exactly a comforting thing. It's way quirkier than a lot of people understand, and unfortunately it all comes to the surface when people start using make. "It stops at a non-zero exit code!" is, unfortunately, far, far from the simple thing it sounds like.
And encountering the "errors? pshaw, whatever" attitude in multiple languages is precisely why I know it's such a bad idea. Were it just Perl or something, I wouldn't be able to tell if it's a bad idea or if Perl is just a bad implementation, but after the decades I've been using these languages, I've come to the conclusion it's just a bad idea everywhere I encounter it.
Once you step off the beaten path, you find that errors from things like:
false | true
Get silently swallowed by bash (this is configurable, but the default ignores such errors). Also, the point about not noticing that a rule didn't create its target is a good one. (That behavior should be configurable; I don't think it is.)
Anyway, with -j, make is as async as pretty much anything else out there.
To be more precise... "make" isn't "bash". There's no problem with "make" here and it has no way to see inside bash's internals. It's a bit like asking "make" to understand python, javascript, and java code and runtimes.
I think the desire would be for that statement to fail. The pipe looks like a logical or, but it's actually for chaining IO. Always a good idea to turn on the pipefail option in your bash scripts.
$ being used for both make and shell replacements, leading to $$$$(var) abominations and the general lack of clarity as to which variables are for which things
There was another comment asking why not just use a shell script? If I don't care about dependencies that's what I would do, but I often do care about dependencies. So I call a shell script from my Makefile to do all the weird and wild things I want to do. Make checks the dependencies and I avoid having to use $$ in my Makefile.
All of its replacements generally involve such a paradigm shift that it's no longer a comparable, to use a real estate term.
I've got a whole list; $ being used for both make and shell replacements, leading to $$$$(var) abominations and the general lack of clarity as to which variables are for which things, many places where lists were clearly bodged in as after thoughts when they should be designed in from the beginning, tabs as meaningful whitespace is a classic but still a problem, .PHONY being a rather ugly hack when there should be a clear distinction between "a command I want to provide" versus "this is how to make a dependency", and while this may not be a user-visible behavior change, taking away all the C defaults so the strace is no longer a nightmare of trying every implicit C rule before actually trying the rule I want it to try. At least a mode of invoking the shell that looks more like a programming language where I pass a clean array of strings rather than the shell language, already a nightmare of string interpolation on its own terms, buried in another string interpolation language sitting on top of it. A thought-out solution to recursive versus included makefiles. And I never became a make master, but by my 21st century standards, trying to use make is just a fractal of bad 1970s ideas hitting me at every turn, so I'm quite sure if I had to work with it a lot more I could go on for quite a while. As it is I think I've forgotten some.
I think people, not entirely illegitimately, have trouble separating the essential concept of make, which I think was quite solid, from the accidental comedy of errors that we have as a received standard. So a lot of make replacements end up running from both of them, and often end up with a much more annoying essential concept at their core, such as a super-heavy-duty enumeration of "these are the exact things you may ever be interested in doing", which puts them behind the eight ball no matter how good their accidental choices may be.