Sponsored Link •
...Wherein we examine what ant fundamentally lacks, and possible ways to address the important problem of build control...
In a previous blog on today.java.net I said some fairly strong things about ant, and I think I ought to say something more, both good and bad. This seems like the place to do it.
First, let us give ant its due. Ant is designed to be a portable way to replace make. Ant was to be platform independent, so the obvious implementation choice was Java, which is fine, mostly. And the obvious data format for the project description -- saying what needs to be built -- was XML, which is not fine, as we shall see.
Ant performs this task with some power, if little aplomb. One can build ant files that will compile Java, C, and many other languages; perform CVS and FTP tasks; build jar files and EJB deployments, and so forth. Ant can run the same configuration without modification, no matter the platform. This is no mean feat. There is a reason why it has been winning many awards.
But when I say it is "with little aplomb", I mean it. Nobody can accuse XML of being an easy read, of course, but if that were ant's worst problem, well, ant is hardly alone in this sin. XML abuse is rampant, and ant is far, far from the worst offender. Given the limitations of XML syntax, ant does pretty well. To see it really suck, try reading Graydon Hoare's essay on XML abuse. (Ignore the odd section headings and stick to the content.)
The real problem is the one I talked about in my brief java.net blog:
Ant is nothing more than the sum of its partsBy this I mean that ant has not learned the basic power of composition, building things out smaller parts. This was the great insight that our Unix forbearers bequeathed us toolsmiths, and it's pretty sad to see it forgotten. In Unix this is done with pipes -- the output of one program can become the input of another. Along with conventions about program output, this allows you to build up something that is more than the sum of its parts. A utility that finds file in the file system can generate a list of files for any purpose: removal, editing, rebuilding, copying, printing, ...
Ant has many kinds of tasks. These are portable because they are written in Java, and these task implementations can rely upon operating system abstractions in the underlying ant platform.
But they almost never work together. There are some common tools for building up lists of files, but if you want a list of files from any other source, good luck. This is why there are two different tasks (one optional) that calculate list of Java class dependencies, and they are incompatible. And if you want a list of Java class dependencies for a task that one of these two tasks can't handle, good luck.
A common quote in our biz is the observation that a good software tool will do things the author never expected1. I doubt that writers of ant tasks are very often surprised.
In fact, I will assume that the value of composable tools is so obvious, I will not belabor it further. Unless you ask...
My experience is that the primary legibility problem with Makefiles are strings and variables. The string operations are primitive, ugly, and limited. So to do anything at all interesting requires cryptic and hobbled work. After that, the next worst problem is the lack of flow control. Loops are put into the shell commands because make doesn't have loops, or (shudder) people use recursion as a replacement. Ugh.
The primary portability problem is obvious: Different system have different commands, and make just executes commands.
So where would one go to leverage existing tools that already know how to do these things well? Scripting languages, of course. Perl, python/jython, tcl, and so on live, breath, eat, and excrete strings for a living, and they are programming languages with real logic. They are ported to every platform that matters (more than Java runs on).
All they are missing are tools to express dependencies and how to apply them to building things. One of the responses to my post pointed me at scons, which does this in Python. It seems just the right direction, although I haven't had a chance to do more than play with scons. I don't claim it is the right answer, but it sure is moving down the right path.
Jonathan Simon's blog entry about how to use ant tasks from jython points towards some hope that we can reuse all the work these folks put into ant tasks. This has often been non-trivial effort, and it would be good to keep this work viable.
One could pick any language, of course, and choosing a winner here would antagonize folks who would just prove they could do it better in the "right" language. I have my preferred scripting languages, but compared to scripting in XML itself (which is where the ant folks seem to be going), no major possibility is worse.
I intend to poke harder at scons, and if it looks good, dive in fully to find out. You'll be seeing a blog here about scons and the lessons to learn from it.
 Google has failed me. Can the death of the internet be far behind? I cannot find an attribution for this quote, despite the obvious set of words and the fact that it's a computer quote that I've heard a billion times. [Note: URL for Graydon Hoare's XML writeup has been updated; 7/1/2005]
|Ken Arnold is a recognized loose cannon in the software business, whose previous fusilades include being an inventor of Jini, designing JavaSpaces, writing books on Java and distributed systems, helping design CORBA 1.0, and (while at Berkeley on the BSD project) the curses library package, co-authoring rogue, and generally enjoying himself. His interests include designing APIs and programming languages using general principles of human factors design because of his radical hypothesis that programmers are human, and other applications of this same principle to software design, management, and production.|