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?
Antcall is relatively rarely used, because:
In other words, antcall is whole new isolated Ant process running.
This means beforeing executing any statement or any tag from target a, ANT makes it sure that target b is executed successfully
And you can call any target using antcall after some statements or tags gets executed from calling target.
The main difference between both approaches is that targets in
depends
are always executed, while targets inantcall
are executed only if the containing target is.A clarifying example:
Here,
b
will always be executed, whilea
will be executed only ifsome.flag
is defined.Here,
b
will only be executed ifa
is, i.e. ifsome.flag
is defined.antcall is the GOTO of ant. It is terrible. It's a great way to make a rats nest of unmaintainable cruft. Next to ant-contrib it's the best way to smell an overly complicated hard to maintain ant file. (even a good antfile is rough)
If your depends are set properly you should be able to run any target up to that point successfully, unlike the antcall pattern.
Another reason nobody has touched on is vizant, the ability to generate a graph of your target dependencies is pretty sweet if it's a complicated build. If you use antcall you're screwed.
I wish @Vladimir Dyuzhev was correct that antcall is rarely used - I've been to a lot of shops where it's the norm.
The biggest difference is that Ant will ensure that dependencies declared via
depends
are called at most once. For example:If I call target
d
,b
andc
are called. However,a
is only called once (even though bothb
andc
depends on it).Now suppose we decide to use
antcall
instead of depends for targetd
:Calling target
d
will now call targetsb
andc
; however, targeta
will get called twice, once forb
and then again forc
.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 whatdepends
is for. So when would you use it? Theantcall
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 thegoto
of Ant--it's evil. Most well-written build scripts simply don't need it except in unusual cases.