ant depends vs. antcall

23,625

Solution 1

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.

Solution 2

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.

Solution 3

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.

Solution 4

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.

Share:
23,625
kostja
Author by

kostja

We are here to learn :) Works and plays with scala, kafka, data, linux

Updated on July 19, 2020

Comments

  • kostja
    kostja almost 4 years

    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?

  • kostja
    kostja almost 13 years
    does this also mean the antcall'ed tasks run in parallel?
  • Vladimir Dyuzhev
    Vladimir Dyuzhev almost 13 years
    No, antcall is synchronous, just like any other task. There is a <parallel> task in Ant for concurrent execution.
  • kostja
    kostja almost 13 years
    Thank you, a highly relevant detail
  • Scott
    Scott over 12 years
    I used to use antcall in order to set up "parameterized" targets that I could re-use, but the macrodef added in 1.6 a long while back makes for a much better case for this kind of reuse.
  • Vladimir Dyuzhev
    Vladimir Dyuzhev over 11 years
    Antcall is a very convenient way to extract repeating steps into a separate task, and call it with different parameters. If vizant cannot support antcall, this is a problem of vizant, alas.
  • thekbb
    thekbb over 11 years
    no. categorically no. program flow in ant is done with depends, antcall calling into the same build.xml is an abomination. If you need to do a similar thing many times with different inputs you're always better off using an ant macro.
  • thekbb
    thekbb over 11 years
    also - properties in ant aren't parameters
  • m2web
    m2web over 10 years
    +1 for the comment about jars with different flavors. I was able to get my run-once part to run and still generate different flavors by moving the run-once part higher up in the hierarchy, so that it wouldn't be called by the antcall parts or their dependencies.
  • Richard Steele
    Richard Steele about 10 years
    Unlike vizant, Grand (github.com/ggtools/Grand) does show the dependencies from <antcall>.
  • luis.espinal
    luis.espinal almost 10 years
    To add to this, a target can be invoked multiple times with <antcall> whereas a target might be executed at most once if all references to them are done via dependencies.
  • Rebse
    Rebse almost 10 years
    Scripts using antcall are a PITA :-( No reason to use antcall anymore after macrodef has been introduced with ant 1.6 in 2003 !
  • Kamil
    Kamil almost 8 years
    When I look at the documentation I see such quote: "By default, all of the properties of the current project will be available in the new project. Alternatively, you can set the inheritAll attribute to false and only "user" properties (i.e., those passed on the command-line) will be passed to the new project." ant.apache.org/manual/Tasks/antcall.html. This is something different than you said.
  • IgorGanapolsky
    IgorGanapolsky over 7 years
    depends aren't always executed. One example is when importing the ant script from gradle, and calling the main target from gradle. In that case, that main target's depends aren't executed.