Antcall is evil

by simpsonjulian on March 13, 2008

Antcall is evil. You’re probably just trying to figure out how to deal with the build you’ve inherited. But trust me on this one. Antcall will hurt you. Use Macrodef. If you use Eclipse you can even complete on macrodefs that you create. How nice is that?. Anyway, read on for the discussion on how wrong antcall is. And drop me a comment if you liked it (or if you didn’t)!

A brief introduction to make

Make is the daddy of Ant. It originally came from the Unix world but it has been ported to just about every computer system, as it’s the de facto way to build c code. Make reads makefiles, which tell make how to do your bidding. Inside the makefile, you declare targets, declare their dependencies, and let make do all the work. Here’s a simple example of a makefile:

jsimpson$ cat Makefile
a: b c
echo “A: I depend on b and c “

b:
echo “B: I depend on nothing”

c: d
echo “C: I depend on d”

d:
echo “D: I depend on nothing”

The format of the makefile is simple. A target begins with a dependency line containing a name, a colon and an optional list of dependencies. The dependency line is followed by one or more command lines that are indented with a tab. The command lines do the work. In the example above you can see that target A depends on targets B and C, and that target C depends on target D. When we execute the makefile, make determines the order in which it should execute the targets to do the work. Have a look:

jsimpson$ make
echo “B: I depend on nothing”
B: I depend on nothing
echo “D: I depend on nothing”
D: I depend on nothing
echo “C: I depend on d”
C: I depend on d
echo “A: I depend on b and c “
A: I depend on b and c

The make that is installed on my Mac decided that the appropriate order in which to execute the targets was B, D, C and then A. It could have chosen D, C, B and then A. It doesn’t matter because you tell make the dependency rules and then make satisfies them. This approach has been working for authors of Unix software since 1977 , thanks to Stuart Feldman at Bell Labs, who wrote the original make. Make is still actively used on many projects today, but for the bulk of Java and .NET projects, you’ll be using Ant and NAnt. This is okay. Make isn’t exactly cross-platform, and the two tools are evolved with support for building their platforms.

How does this help me write good Nant or Ant buildfiles?


What you are doing when you write a makefile, or build.xml or project.build is declaring dependencies. What the build tool (Ant ) does with those dependencies is create a dependency graph. We can visualize the dependency graph of our simple build:

It becomes very important to specify the dependencies of each target correctly. If you write a build target that doesn’t declare it’s dependencies fully or correctly (say, it actually depends on the output of another target, which is run sometimes) then you end up with a broken or unreliable build. It’s an easy mistake to make, especially as complexity on your project grows. But how does all this relate antcall?

Antcall seems okay at first glance. Each task will execute a named target in the same buildfile as the calling element. Which is really convenient if you explicitly want to invoke a target at a specific point in your buildfile. But what if that target has dependencies? The Antcall documentation hints at the pain:

When a target is invoked by antcall, all of its dependent targets will also be called within the context of any new parameters.

If your antcall (or Nant call) target has no dependencies, then you have done nothing wrong but violate the dependency based style of the tool. If it has dependencies, then they will be relentlessly run every time you call the target.

One pattern I have seen a lot of is using the [ant]call to specify dependencies in order, rather than declaring them as such:

<target name="chico"/>
<target name="zeppo"/>
<target name="harpo"/>
<target name="groucho">
<antcall target="chico"/>
<antcall target="zeppo"/>
<antcall target="harpo"/>
</target>

In a twisted way I can see why the idea is attractive: You want to be sure of the order of target execution. To be really sure, you need to specify dependencies on the targets. So in this case you’d declare that harpo depended on zeppo, for example.

<target name="groucho" depends="chico,zeppo,harpo">
</target>

Another aspect that I haven’t covered yet is reuse. If you want to try and invoke a target several times with different parameters, the dependency model doesn’t really cut it. Before Ant 1.6 came out, there really was no choice but to use antcall.

Anyway, my advice for anybody using antcall is to substitute it for macrodef, where you really need reuse.

Thanks to T Ashitani for the online dot implementation.

Share with the group:
  • Digg
  • del.icio.us
  • Facebook
  • DZone
  • LinkedIn
  • Slashdot
  • StumbleUpon

Related posts:

  1. Better Apache Ant Builds Abstract: We did two CITCON sessions here; Joe Schmetzer...
  2. A way to cool dependency Hell? How to break a deploy: Take one codebase. Sieve in...

Related posts brought to you by Yet Another Related Posts Plugin.

{ 1 trackback }

2008 in posts — The Build Doctor
January 2, 2009 at 1:45 pm

{ 3 comments… read them below or add one }

1 jochen March 14, 2008 at 11:08 am

Your blog entries are only printable if you have sheets which are 100 meters long ;-)
BTW we are largely trapped in the antcall hell…

2 Julian March 14, 2008 at 5:20 pm

Hi Jochen,

Thanks for letting me know. I know I have loads of CSS work to do, and the list just got longer!

Are you able to comment more on your Antcall hell? Sorry to hear that you’re trapped there.

Julian.

3 Stephen Chu March 17, 2008 at 5:38 am

Back in the NAnt days I did not like calls either. There wasn’t anything I couldn’t do with depends, and in fact when I used depends, to use calls is a smell in my script, because my target I am writing is doing something it cannot do itself, meaning it is getting complicated, or it is not cohesive enough as a unit of work. Bad scripts lead to managing nightmares.

I wrote some of my thinkings in this little post of mine: http://www.stephenchu.com/2006/03/pragmatic-nant-scripting.html

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Previous post: Jetbrains eat their own dog food

Next post: Graphing your CruiseControl build times with Gruff