ant depends vs. antcall
When defining sequential build steps I use the depends
attribute of the target
element. I have recently seen an ant file, where the build sequence was defined by antcall
elements inside the targets.
To illustrate :
<target name="a" depends="b">
...</target>
vs
<target name="a">
<antcall target="b"/>
...</target>
Is there a real difference between the two approaches? Is one of them preferable?
The biggest difference is that Ant will ensure that dependencies declared via depends
are called at most once. For example:
<target name="a" />
<target name="b" depends="a" />
<target name="c" depends="a" />
<target name="d" depends="b, c" />
If I call target d
, b
and c
are called. However, a
is only called once (even though both b
and c
depends on it).
Now suppose we decide to use antcall
instead of depends for target d
:
<target name="d">
<antcall target="b" />
<antcall target="c" />
</target>
Calling target d
will now call targets b
and c
; however, target a
will get called twice, once for b
and then again for c
.
In other words, antcall
sidesteps the normal dependency rules that are the cornerstone of Ant.
I don't think antcall
should be used as a substitute for normal Ant-like dependencies; that's what depends
is for. So when would you use it? The antcall
task does allow you to control what properties and references are defined (which is why a new Ant environment is created--and why it's so slow) so it can be used to create variants of the same thing; e.g., maybe two jars, one with and one without debug symbols.
Overusing antcall
, however, creates slow, brittle, and hard to maintain build scripts. Think of it as the goto
of Ant--it's evil. Most well-written build scripts simply don't need it except in unusual cases.
The main difference between both approaches is that targets in depends
are always executed, while targets in antcall
are executed only if the containing target is.
A clarifying example:
<target name="a" depends="b" if="some.flag">
</target>
Here, b
will always be executed, while a
will be executed only if some.flag
is defined.
<target name="a" if="some.flag">
<antcall target="b" />
</target>
Here, b
will only be executed if a
is, i.e. if some.flag
is defined.
Antcall is relatively rarely used, because:
The called target(s) are run in a new project; be aware that this means properties, references, etc. set by called targets will not persist back to the calling project.
In other words, antcall is whole new isolated Ant process running.