Reputation: 4614
Suppose I have a simple build script with the following 4 targets:
build
- Compile's the project's code, depends on init
init
- Sets up the build environment, depends on nothing clean
- Deletes all files generated by build
and init
, depends on nothingall
- Simply cleans and then builds, depends on clean
and build
<project>
<target name="build" depends="init">
<echo>Building the project</echo>
</target>
<target name="init">
<echo>Setting up the build environment</echo>
</target>
<target name="clean">
<echo>Deleting all generated files</echo>
</target>
<target name="all" depends="build,clean">
<echo>Full build complete!</echo>
</target>
</project>
The problem here is that the order of init
and clean
is ambiguous in Ant. If clean
is called, it needs to run before all other targets, including init
. However, init
cannot have depends="clean"
because we don't always want to run clean
.
I realize that reversing the order of build
and clean
in the all
target's dependencies (i.e. depends="clean,build"
) would technically get them to run in that order, however I don't consider this to be a satisfactory solution. Ant will still consider these targets to be siblings on the dependency tree, and will not actually enforce this order at all.
Another "solution" of course is to just hard code the ordering by using sequential <antcall/>
tasks. This might be what I have to eventually fall back on, but it's something I'm trying to avoid (for multiple reasons that probably aren't worth expanding on).
Also, I'm aware that Gradle has exactly this feature built in (believe me, I'm jealous of it), but at this point my company's project is deeply entrenched in Ant, so switching really isn't an option.
EDIT - To give a better idea of the sort of thing I'm looking for, here's an example using features that I wish Ant had:
<condition property="init.depends.list" value="clean" else="">
<contains string="${ant.project.call-graph}" substring="clean" />
</condition>
<target name="clean" />
<target name="init" depends="${init.depends.list}" />
After reading the manual page on Ant's bindtargets task, I'm starting to think Ant's target dependency list is immutable as part of its core design philosophy, so there might actually be no good answer to this question.
Upvotes: 1
Views: 883
Reputation: 903
From the Ant Targets documentation:
Ant tries to execute the targets in the depends attribute in the order they appear (from left to right). Keep in mind that it is possible that a target can get executed earlier when an earlier target depends on it.
So unless your init and clean targets become more complex with additional dependencies, you can count on the ordering to be in order. So depends="clean,build"
would work reliably.
Upvotes: 0
Reputation: 7051
If you want to ensure that init
never runs before clean
. Then you can use a property to serve as a flag:
<target name="init">
<property name="init-called" value="true"/>
</target>
<target name="clean">
<fail if="init-called" message="init ran before clean"/>
</target>
If init
runs before clean
, the init-called
property will be set and the <fail>
task will fail the build.
Another option is to have all
depend on two targets: enable-clean-target
and init
. enable-clean-target
would set a property that would be used by the if
attribute of the clean
target:
<target name="enable-clean-target">
<property="run-clean" value="true"/>
</target>
<target name="clean" if="run-clean">
<!-- ... -->
</target>
<target name="init" depends="clean">
<!-- ... -->
</target>
<target name="all" depends="enable-clean-target, init">
<!-- ... -->
</target>
The init
target explicitly depends on clean
, but clean
will only run if enable-clean-target
ran earlier in the build.
Upvotes: 1