Is there a way to guarantee that an ant dependency is run only once?

ant

Solution

You should remove the `antcalls` and add `do.first` and `do.second` as dependencies of `do.several`:

<target name="do.several" depends="setup, do.first, do.second">
</target>

This will make sure, that `setup` is only called once:

setup:
     [echo] In setup

do.first:
     [echo] In do.first

do.second:
     [echo] In do.second

do.several:

BUILD SUCCESSFUL
Total time: 0 seconds

Documentation says why a property set in setup does not work with antcall:

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.

Problem

My question is similar to avoiding-re-building-prerequisites-in-ant, except that my need doesn't involve created objects, but processes invoked, so the solutions discussed there won't work for me. At least I think so - but I'm new to ant. My situation is that I'm writing a set of ant targets, and I need the lets-call-it setup target to be executed once and only once, no matter which target is invoked. Here's a greatly simplified example: ``` <?xml version="1.0"?> <project name="Ant_Test" basedir="."> <target name="setup"> <echo message="In setup" /> </target> <target name="do.several" depends="setup"> <echo message="In do.several, calling do.first" /> <antcall target="do.first" /> <echo message="In do.several, calling do.second" /> <antcall target="do.second" /> </target> <target name="do.first" depends="setup"> <echo message="In do.first" /> </target> <target name="do.second" depends="setup"> <echo message="In do.second" /> </target> </project> ``` I need setup to be invoked exactly once, regardless of whether do.several, do.first, or do.second are invoked. With my naive attempt above, invoking do.several results in three calls to setup. I've thought of setting a property (let's call it setup.has.been.invoked), and using that to conditionally invoke setup from within each target, but it appears that property setting is limited to the scope it's done in, so if in setup, I set setup.has.been.invoked to true, that value only exists within setup. What am I missing? Is there a section of the tutorials or online documentation I've skipped? Any pointers or hints?

Original source