Which is better: The Java ApacheAnt
tool or the Unix MakeProgram
[Editing Note: Most of this discussion was originally written on the ApacheAnt page.]
I highly recommend avoiding Ant
. It lacks the basic ability of make
to work with other tools well, in particular to work with tools for computing dependencies. That is where much of the value of make lies: without it, make is just another automation/scripting tool, like Ant - and Ant isn't as good a scripting tool as a scripting language. I've worked with, and come to love, many build systems; Ant is the worst I've ever seen. Its documentation is substandard, its code abysmally inefficient in places, and its failure to even match make in functionality is not good. The worst thing about Ant is the need to define a new "task" for each other tool with which you wish to integrate: make uses the Unix toolbox philosophy, but Ant thinks of itself as the centre of the universe. Dependency management and difficult integration with other tools are the two main reasons why Ant is worse than any other solution in this domain. -- JamesDennett
Wow. Worse than any other tool in this domain? Geez, you should see the piece of junk I wrote to automate builds. Seriously, readers should consider James's opinion as about as negative as you can get. (And some of it is incorrect, e.g., his lack of awareness of the exec task). In James's world, Unix is the center of the universe. For those of us not developing under Unix, getting the average makefile to run under any other platform is rarely worth the effort. A correctly written build.xml should run as well under Windows as it does under Unix. -- KellyDenehy?
The lack of dependency checking in Ant is somewhat made up for by dependency checking in Java compilers. If you've got non-Java sources in your project, you'd probably have to use make as well as (or perhaps instead of) Ant. It'd be fair to say that Ant's feature-set is Java-centric. -- AlexValdez
Ant is doing quite a good job at dependency checking for Java when you use the depend task; work for tasks that wrap C/C++ compilers, including dependency computation for these languages, is on the way (http://sourceforge.net/projects/ant-contrib/
). Oh, you certainly don't need to write tasks of your own to integrate with other tools. If you can do it in make by using an external command, you can do it with Ant's exec task as well.
I have to concur with the recommendation to avoid Ant at any and all costs. Ant's dependency tracking is singularly verbose, error-prone, and impossible to automate in any meaningful way. With, at least, GNU Make, I can express a set of dependencies using environment variables, and use macros and %-substitutions to synthesize a wide variety of other dep-chains from that single, master list. Nothing, so far as I am aware, comes close to this in Ant. As a result, massive violations of OnceAndOnlyOnce result. It often gets so bad that engineers choose to disregard Ant's ability to properly track dependencies entirely, resorting to flat, ordered lists of projects to be iterated via the foreach construct, leaving the programmer to decide where to insert new projects or modules. --SamuelFalvo?
is bad because of its human unfriendly syntax, Ant
is worse. Why has no-one written a proper/simple build tool yet? Weird.
I think you'd get a lot of disagreement on that from those who've used both. I can't remember what $< means in a makefile, but most of the XML tags used in Ant build files are relatively intuitive. And there are some pretty nice XML editing tools out there that hide the complexity from you, like Pollo - http://pollo.sourceforge.net/ - which includes built-in support for Ant. -- KellyDenehy?
I'm sorry, Kelly, but you're dead wrong on this one. I have the most unfortunate privilege of having to maintain Maven, Ant, plain makefiles, and GNU Autotools input files in my current professional capacity. Out of all of these, for as horrid as Autotools is, I cannot express emphatically enough how I prefer dealing with Autotools far and above
having to deal with Ant. --SamuelFalvo?
Why is Ant
so popular? Build tools are fundamentally expert systems that enable developers to express dependencies between targets and resources. At build time, these tools determine an appropriate ordering to construct the desired target(s). Old-school tools such as make
provide developers with the ability to concisely express complex rules. Based purely on the fundamentals of a build tool, Ant is currently the weakest major competitor.
Since the fundamentals have been better expressed in other tools, I pushed on to find the 'compelling' reason to use Ant. With a little help from ant.apache.org and the Java development with Ant book, I have come up with the following 'compelling' reasons to use Ant:
- Ant's configuration files are XML-based. This is bad. XML is verbose and difficult to read and is therefore not an expressive way to represent dependency rules.
- Ant is extended using Java classes. Traditionally, one would extend using a scripting language that would allow for a quick turnaround and a declarative result. With a Java class, you get neither.
- Ant solves the dreaded make tab problem. I shudder to think there are armies of developers who actually consider a product, given this caliber of argument.
- Ant is simpler to learn and maintain. I agree that Ant is simpler to learn, but since it is more verbose and less powerful, I have found that in the two years that I have used Ant that it is significantly more costly and frustrating to maintain.
- Ant is cross-platform. Now I finally agree with something. In most of my projects, all developers use Linux and Solaris. So we do not have cross-platform issues. When we do we will consider Ant (or even better, we could use CygWin).
- Ant is quicker. This is completely wrong. The single java vm advantage is easily outweighed by the ability to better express rules between dependencies, thereby ensuring that the least amount of work is done to construct a target.
No, I will not use Ant in my next project. Learning to use Ant after make and cook has been like learning C after being used to a functional language.
I've recently worked on a rather large ant KludgeFest?
(for lack of a better term). Our system consisted of about 300,000 lines of java code (no c or anything mixed in). Our ant build system checked out the base system, as well as various other modules from CVS and built it. We also worked with CruiseControl
(I contributed a patch to their cvs task), and JUnit, and did many sundry and generally odd things.
It wasn't a good experience. Througought the 2 years of its evolution, it broke a lot. When it broke, the xml include mechanism hid the actual location of the problem. The api available via the <script> target was terrible, and only semi-documented, and was generally pretty weird.
Oh, and it was slow too, and it tacked garbage onto your compiler output, breaking tools that wanted to parse it.
The worst part of it was, I was behind the push to get rid of make. Make worked flawlessly, did everything ant did, was more x-platform than java, oh, and it was fast. But, of course, it had to go, since I didn't want to learn make when I wanted to modify something. A classic case of massive idiocy on my part. The graybeards did indeed warn me, though they never said "told you so".
Towards the end, it occurred to me that ant was trying to use a declarative sort of language to describe a process, whereas make actually lay down the letter of the process line by line. Much easier to think "what to do next" than "what declaration do I make to describe what it is I want to do".
Now that I am older and a little wiser, though, I still don't know much about make, I'd be sure to find some intern or "the new guy" to force into maintaining a make-based build system in future projects.
Indeed, declarative semantics are what differentiate Ant. Trying to make Ant do things it wasn't meant to do, like looping through a list of subprojects rather than declaring the dependencies and letting Ant work out the details is driving screws with a hammer. As a member of the ant-dev list and a contributor to the project, I regularly see this nature misunderstood, and calls for a looping task or some sort of if/then/else construct get rejected with a polite, "That's not the Ant way". Learning to use Ant after make
is like learning a functional language after C. But once the real
meaning of <target name="all" depends="subproject1, subproject2, subproject3... subprojectN"/> sinks in, you will give literal-minded make the boot it so richly deserves. -- StevenNewton
I don't see how the declarative semantics of dependencies differentiate it from anything, Make's are richer. It isn't clear to me how Ant is Declarative in nature. It better resembles a Procedural Language; if it were true that you just declared dependancies and Ant would get on with it, it would be more like make. Whereby the author can, just about (though often linking needs explicit lines), declare the components to be pieced together and make will use implicit rules to derive the commands to be run. Is it me, but for Ant to be truly declarative it would take declarations of facts and produce a result, instead "targets" are glorified procedures and dependencies are always run, making dependencies statements of targets that must be run first. It seems to me, everything is stated in the Ant file itself. On looping: I might be wrong, but don't all ModelsOfComputation
contain control machanisms? Is your suggestion that blocks of sequence be separate targets setting properties to select if conditions aka <target name="..." if="prop"> .... and to recurse for loops? What I was really disappointed in when I saw Ant was that for such a DomainSpecific?
language it did little to remove the complexity; strange - from a community already sold on the benefits of high-level languages, it's almost a build assembler.
What I am trying to say is, it seems to me, from what I've heard, that Ant is being justified on some deep theortical basis. When everyone really knows it's a hack to get the job done, why try and present the style guide as though it has some deeper meaning? Ant is very useful, but is it a build tool (when it is more general purpose than that)?
It would be great if the Java community fixed the weaknesses in make (without throwing away it's benefits) and called that its build tool of choice. -- AndyGavin
One should not iterate through subprojects in make
either. See RecursiveMakeConsideredHarmful
I think ant is great for simple things. The use of XML is ugly, but it works (luckily, they did not use XML for Java
itself <java> <class name="Server" extends=".."> </class> ... </java> ;-)
But to do this make two-liner (which says call idl if the idl file is newer than the header) in ant is horror:
Server_s.h : Server.idl
idl -i Server.idl
And that undersells make
. On a large project, you'd set up an implicit rule which would know how to build _s.h from idl. So most modules in the project would just have the line
Server_s.h ... : Server.idl
where ... is the other targets depending on Server.idl. I'm not a make advocate, though, as it occasionally doesn't give you what you really want either.
[Ant] is very fast, much faster than a make-based process could ever be.
That's just not true. See http://www.freshmeat.net/projects/jvmd/
Take a look at http://www.cpmake.org
- it solves problems where ant
isn't anything like Make. Make is about describing dependencies between files, and how to build files. Ant is about dependencies between "tasks", and is really more of a way of gluing build scripts together. If no full rebuild is necessary, every task in Ant has to figure that out on its own, as well as a proper build order for the components.
A task in Ant is what you'd call a phony target in make, and the actions triggered by tasks are really just smart build scripts. It's the tasks shipped with raw Ant that just Do The Right Thing (in most situations, anyway) that got Ant its reputation, not the fact that its architecture was in any way superior to make. Not that there was anything wrong with that, but when push comes to shove, both are equally unusable for solving more intricate problems. Make is too convoluted and brittle, Ant is too high-level. -- ArneVogel