GNU Make 4.0 Released
jones_supa writes "A new major version of the classic GNU Make software has been released. First of all, Make 4.0 has integration support for GNU Guile Scheme. Guile is the extension system of the GNU project that is a Scheme programming language implementation and now in the Make world will be the embedded extension language. 4.0 also features a new 'output-sync' option, 'trace-enables' for tracing of targets, a 'none' flag for the 'debug' argument, and the 'job server' and .ONESHELL features are now supported under Windows. There are also new assignment operators, a new function for writing to files, and other enhancements. It's been reported that Make 4.0 also has more than 80 bug-fixes. More details can be found from their release announcement on the mailing list."
I myself prefer GNU Ryu and GNU Ken, but a lot of people seem to do well with GNU Chun Li.
Didn't they plan to introduce a Lua frontend to GUILE? Does anyone of you know what happened to that?
You've quoted exactly from the original article, with only a blind link to it. You have not credited the original author whatsoever. jones_supa should receive a permament HORRIBLY EVIL karma rating, and all his posts should start with -9999 moderation.
This looks good.
The --trace option is really nice. For some reason people think it is prettier to have makefiles not print put the compile lines. It is, of course, until it breaks.
Make is one of those widely misunderstood tools. Despite being far simpler than, e.g. C it seems to be understood much worse. It's also sad that it diverged long ago, but it's good to see GNU trying to make it compatible with the divergent BSD and POSIX variants too.
One Make to rule them all! While it seems fashionable not to use the GNU tools these days (for instance distros using less featureful and now slower AWKs than gawk by default), GNU Make is truly the superior one. It is very featureful and an excellent part of a build system.
SJW n. One who posts facts.
Have the developers made a statement concerning backward compatibility with makefiles developed for GNU make 3.80 (or 3.76, etc)?
There is a lot I don't like about Make, including GNU Make. The extensions it has received over the years make it incredibly baroque. I can't work on nontrivial makefiles without keeping a copy of the reference manual open to look things up, and the magic differences between tabs and spaces mean I need syntax highlighting to make sure I know what my makefiles really will do.
So now GUILE integration. How many Slashdot users are big fans of the Scheme language? I appreciate the elegance but I don't want to work in it, and I don't look forward to trying to debug makefiles that make heavy use of it.
I'm not sure what to use to replace Make though. I'm a Python guy so I would probably want Scons or something like that, but Ruby fans probably want Rake, Java fans probably want Ant, and in general I don't think there is any consensus on what might be the best replacement for Make.
lf(1): it's like ls(1) but sorts filenames by extension, tersely
Why isn't there a changelog on the gnu make website?
I see a lot of words but not a lot of arguments. State your position on _why_ you should not use it as an extension language.
Did they get rid of the required TAB character in front of the rules? Or at least report a non-TAB character?
He's saying that he's too stupid to understand functional languages, therefore functional languages are bad.
people still use make? i switched to Ant a long time ago and have never looked back.
He's saying that he's too stupid to understand functional languages, therefore functional languages are bad.
It's more like the average Joe-sixpack developer doesn't want to have to spend weeks learning the subtle distinctions between "let", "let*" and "letrec" just so they can add some scripting to their makefiles.
No matter what you do to it, Make is an antiquated pig. No offense to the GNU folks, who generally make the best versions of the traditional *nix utilities, and yes, you do need to keep Make around for backwards compatibility, yada, yada, yada.
What's really needed is a ground up re-think of how to create a build utility. A number of folks have tried it. I used to use SCons, and before that it's Perl based predecessor, Cons. The reason I'm not using them now has nothing to do with the software, which I though was excellent. The project lead's idea of alpha is what some people call final release.
I suspect the biggest problem to a widely used Make alternative is the sheer variety of options out there. Nevertheless, what are other people's experiences with build utilities other than Make?
Most abandoned make long ago, in favour of automake/cmake/etc.
At our company we use SCons to build our large projects, which span several platforms (mobile, desktop and consoles), and have plenty of autogenerated code, shaders, etc.
My point of view is that if you are going to need a complex, scripted build system, why not use a friendlier and more accessible programming language such as Python?
Does it build Linux, this time ?
The Linux build system broke when upgrading GNU Make from 3.81 to 3.82, and all stable branches had to add a fix to handle the changes.
Make might not have many friends, but when something doesn't go as expected (eg, compiling an Ubuntu utility on openwrt) it's usually straightforward to dive in and change things. scons and cmake are nice, too; nicer when they work but more painful when things break. And as for the abomination that is autoconf. WTF? 2 hours chugging through ./configure to give an error like "Can't compile -llibbaz" which it turns out means I'm running autoconf 1.2.8 and need autoconf >= 1.2.11 Now, how long before GNU standardises on guile-scripted makefile generated from configure scripts from autoconf autogenerated by cmake from a ./install.sh script???
Some of us actually have directories like that...
Strictly spoken, it's not functional.
Also, its language is only good for the lazy parser writers.
Human need contrast, but all lisp-likes provides is data structure like XML. (Haha, this comparison must make LISPers mad.)
It wouldn't even make sense to cheat this away with clever syntax highlighting, because it would be a logical flaw and pretty pointless, because then one could implement/use a good syntax anyway.
Also, add on paradigms can't be used by the same logic, so no CLOS or similar crap is allowed.
The best about lisp-likes is that some runtime implementations are really good.
That makes me raise the question, why do average Joe-sixpack developers need scripting in their makefiles to begin with? Shouldn't they be using something that does everything for them already?
I don't think so. Scheme has enough issues to where I'd rather use lisp if I feel the need to go the functional route (object-oriented model is horribly mis-defined if not out and out plain broken, whomever implements that language needs to understand how valuable "standard" structures like arrays and hash tables are, and I know some love the multiple return types but I think they're a huge pain in the ass.)
Python: 'And then suddenly you have a language which says "we're all stuck with whatever the whiniest coder wants".'
Human need contrast, but all lisp-likes provides is data structure like XML. (Haha, this comparison must make LISPers mad.)
I hope you realize that you've just started a war that will make the Wars of the Reformation seem tame. Get out of Bohemia while you can! I'm staying neutral.
Why do we still insist on using make when we have much better tools, such as git tup. http://gittup.org/tup/
Tup understands the dependencies between source files, so if you modify a header, only the appropriate source files will be rebuilt, only the libraries/binaries that are dependent on those will be relinked. Whereas make spends most of its time figuring out what to build and what not to.
Hasn't everyone moved to Ninja yet?
I just did it for the trullz.
His arguments were clear to me. Too many bloody brackets!
but all lisp-likes provides is data structure like XML. (Haha, this comparison must make LISPers mad :)
XML is just an ugly syntax for S-Expressions :)
More seriously, the reason for Lisp's syntax is that it makes it easy to write Lisp code that manipulates Lisp code (since Lisp code is really just a list). In this Lisper's experience, that more than makes up for the unique syntax
Don't worry, guile is basically a pink stain where a horse used to be that the GNU guys insist on beating. It's been around for literally 2 decades and in that time has largely been ignored.
As soon as one needs anything more complicated than "compile these files", it's time to use a better build system or write one.
I've seen complex pure-make based build systems.. it's terrifying stuff.
SQL is being replaced with NoSQL DBs + imperative code. Want a join? Code up a couple of loops.
How long before makefiles get replaced with something imperative? Is there anything else widely used that's declarative?
Lisp is great as a language for Emacs. It has also been well used in some other contexts for customization. I dont doubt that Scheme would work too in some instances. However often the pure functional nature of Scheme would seem to collide with the quick-and-dirty nature of scripting languages, but could be worked around (a lot of Scheme implementations relent and add some more traditional Lisp features instead of staying minimalist).
However Scheme being good at something doesn't say too much about Guile. Guile last I looked seems larger than I would expect a Scheme to be.
In this Lisper's experience, that more than makes up for the unique syntax
Thank you! It drives me nuts when Lispers defend the human readability of the "unique" syntax by saying things like "it's simpler" (true for a computer, a human not so much) and "you don't have to worry about operator precedence" (you can get the same effect in C by putting everything in parentheses, which makes it look like Lisp).
By contrast, you admit that it's a tradeoff. I don't have enough Lisp experience to say whether it's a worthwhile tradeoff, but it's a very solid argument.
Being simpler for a computer means it is simpler to write evaluators for LISP expressions. Because of the simplicity of LISP an evaluator + applicator gives you a compiler or runtime environment. That is a huge huge advantage.
You really can only do LISP in LISP. The real tradeoff is between layers of DSLs vs. layers of libraries as a way of designing large systems. Libraries obviously won some of the fights for example on operating systems or large application. While on places like networking, or hardware DSLs won.
Three minutes, tops.
Make 4.1 will be able to read mail.
Also, its language is only good for the lazy parser writers.
Nothing wrong with "simple to parse" (which XML is not; go on, try it, with a really simple single byte lookahead parser, while making sure you're getting all the little details and corner cases right).
Human need contrast, but all lisp-likes provides is data structure like XML. (Haha, this comparison must make LISPers mad.)
To me you're sounding like you didn't like "the novelisation of the movie", when the book came first. Lisp is a lot more useful than XML, and easier to parse to boot. Both lack in readability but the former is a lot less arbitrary.
If you want to slag something, I'm told it's actually easier to stick some things in xml then run xslt/xpath/xquery on it (just one approach wasn't enough--yet somehow all three are still less expressive than SQL unless you count byzantine tree traversions induced by "going xml" as "expressive"), than it is to do it directly in java. Hence, xml+friends are popular with the java crowd.
Tangentially, I stumbled on a lisp interpreter done in awk not too long ago. That is a pretty neat hack.
How is the state of that?
Some Qt insider?
Having tried to deal with Scala's macros I have joined the camp of "it's a seriously worthwhile tradeoff".
Honestly doing anything with reflection in Scala (or pretty much every non-Lisp) is just horrifyingly unintuitive (and as a result: painful). In a Lisp you're just manipulating lists using typical list manipulation functions, it is, comparatively, a piece of cake.
By having the object code format be JVM bytecode, CIL, or LLVM bitcode.
There are a lot of build systems that provide more built-in features than straight-up make. Heck, GNU make itself has LOTS more features than POSIX make.
But many of those more-automated build systems run on top of... make. In particular, if you use cmake or automake/autotools, they *generate* makefiles, so you still need a capable "make" program. In fact, you *want* a "make" underneath with lots of capabilities, so the tool you use directly can generate better results.
Ant and Maven are nice tools... but usually they're only used with Java. Rake is great, but is typically only used with Ruby. I like Python (the language), but there are several articles showing that at least at the time Scons was *slow* (and thus had trouble scaling). Autoconf's syntax is still baroque, but if you follow certain conventions it's actually not too bad, and it's much easier to use now that a number of annoying bugs have been fixed.
For general-purpose build systems, the autotools or cmake are still reasonable build systems to look at (unless you're using Java or Ruby). And since they generate makefiles, it's important to have a great tool underneath to process the makefile, even if you don't use make directly.
- David A. Wheeler (see my Secure Programming HOWTO)
Previous poster: "Being simpler for a computer means it is simpler to write evaluators for LISP expressions. Because of the simplicity of LISP an evaluator + applicator gives you a compiler or runtime environment. That is a huge huge advantage."
Yes, but that doesn't require using the old s-expression notation from the 1950s.
Check out http://readable.sourceforge.net./ This adds additional abbreviations to s-expressions, just like 'x currently means (quote x), so that people can produce much more readable code and data. It's implemented in Scheme and Common Lisp, and is released as open source software using the MIT license.
- David A. Wheeler (see my Secure Programming HOWTO)
Make scales just fine. Badly using make, through mistakes like using recursive make, causes scalability problems.
The paper "Recursive make considered harmful" by Peter Miller identifies common mistakes in using make, and how to fix them. The biggest mistake is using recursive make; this is a common mistake that is NOT required by make. Once you stop making this mistake, make is suddenly much faster.
Two other issues with standard make were not part of POSIX, but they are now:
Issue 1: Historically, standard make only implements deferred assignment (where values are calculated when referenced, not when set). This meant that as size grows, there was an exponentially increasing calculation effort (eek). Miller recommends using immediate assignment op, but although GNU make has one (as :=) that wasn't in the POSIX standard. He also suggests using an appending assignment (+=_, which wasn't in POSIX either.
Since then, POSIX has added the immediate-assignment operator ::= and the appendix-assignment += (see http://austingroupbugs.net/view.php?id=330). GNU make 4.0 implements "::=", so you can now start using it. This gets rid of a major scalability problem.
Issue 2: The "obvious" ways to implement automatic dependency generation in make require the ability to "include" multiple from one line, and the ability to silently ignore errors when including, and those weren't in POSIX either. These have since been added to POSIX (in http://austingroupbugs.net/view.php?id=333 and http://austingroupbugs.net/view.php?id=518).
Just getting something into the POSIX spec doesn't cause anything magical to happen. But if a capability is in a standard, it's way more likely to be implemented, and people are far more willing to depend on it.
- David A. Wheeler (see my Secure Programming HOWTO)
See page 184 of the Unix Haters Handbook, http://web.mit.edu/~simsong/www/ugh.pdf. That has to be the most obstinate bug in the world.
Helpful comments in the source code:
if (wtype == w_eol) /* There's no need to be ivory-tower about this: check for
{
if (*p2 != '\0')
one of the most common bugs found in makefiles... */
fatal (fstart, _("missing separator%s"),
(cmd_prefix == '\t' && !strneq (line, " ", 8))
? "" : _(" (did you mean TAB instead of 8 spaces?)"));
continue;
}
So they detect it, and they'd rather insult the user. But "no ivory tower", no no, we will just not parse a space when the ATT code only parsed tabs. It's a "makefile bug", not a "make bug". Sure.
And for the fun, I just tried to build make. On MacOSX, supposedly some kind of Unix that I head a few folks actually use to build stuff. Could be a prime citizen. OK, no configure out of the box with the git repository. OK. No makefile, obviously. No install script. Bogus information in the INSTALL that tells me to run nonexistent configure. Well, running the magic incantation, aclocal ; autoheader; automake ; autoconf. Still does not work, missing files like config/compile. Running automake --add-missing. Whatever. Still an error where it's looking for po/Makefile.in.in. Huh?
So to build make, I need not just make, but four other utilities and makefile input inputs? WTF?
Make alone was bad enough. But it was not good enough for portability, so autoconf was added. But it did not work so automake was added. But it did not work, so... And now at version 4.0, we have a system here you need half a dozen commands just to build the damn thing, and it still does not build out of the box. Seriously?
This whole archaic build system is doomed. Go cmake.
-- Did you try Tao3D? http://tao3d.sourceforge.net
Now you should be able to GNU Make 4.0 GNU HURD
Subtle? You mean ... parallel binding, sequential binding, and recursive binding? That's not so hard to get. Especially since you can define all of them in terms of let to elucidate their meaning... let* just expands into (let ((binding one)) (let ((binding two)) ...)), letrec is just (let ((binding-one *unspecified*) (binding-two *unspecified*) ...) (let ((binding-one actual-definition) (binding-two actual-definition)) ...)
Although using let* is a sin (usually it is used to hide imperative programs, something that annoys the piss out of me in SML with its default sequential let...).
HAL 7000, fewer features than the HAL 9000, but just as homicidal!
Guile is pretty much Scheme with the Common Lisp library and POSIX support bolted on. It's really convenient for scripting when bash becomes too unwieldy. The only thing that sucks is that it doesn't support the scheme shell process notation any more, but that's mostly my fault since I started porting it to guile 2.x a few years ago and kind of trailed off like the lazy hacker I am.
HAL 7000, fewer features than the HAL 9000, but just as homicidal!