Reputation: 7541
I have a shared ant script b.ant
which internally use antcall
. It calculates a property that the client scripts use. I use include
instead of import
client scripts to avoid unintentional overwriting of targets, but this gives me a problem with the antcall.
When using include
all targets in b
are prefixes, and depends
attributes in b
are updated accordingly. This is however not true for antcall
. Is there a there are way to handle this, i.e. make antcall
always call the "local" ant target?
I can workaround this by using import
, but then I'll get all the overwrite problems. It is not possible to use depends
instead of antcall.
Example files
I have two files:
a.ant
<project>
<include file="b.ant" as="b" />
<target name="test-depends" depends="b.depend">
<echo>${calculated-property}</echo>
</target>
<target name="test-call" depends="b.call">
<echo>${calculated-property}</echo>
</target>
</project>
b.ant
<project>
<target name="depend" depends="some-target">
<property name="calculated-property" value="Hello World"/>
</target>
<target name="call">
<antcall target="some-target" inheritrefs="true"/>
<property name="calculated-property" value="Hello World"/>
</target>
<target name="some-target"/>
</project>
Example output
Calling test-depend
works as expected but test-call
fails with this output:
b.call:
BUILD FAILED
D:\ws\rambo2\ws-dobshl\ant-test\b.ant:6: The following error occurred while executing this line:
Target "some-target" does not exist in the project "null".
Total time: 258 milliseconds
Upvotes: 0
Views: 2069
Reputation: 7041
Give a name
to the <project>
in b.ant and then change the target
of the <antcall>
:
<project name="b"> <!-- Give the project a name -->
<target name="depend" depends="some-target">
<property name="calculated-property" value="In b.depend"/>
</target>
<target name="call">
<!-- Specify the name of the project containing the target -->
<antcall target="b.some-target" inheritrefs="true"/>
<property name="calculated-property" value="In b.call"/>
</target>
<target name="some-target"/>
</project>
The result of ant -f a.ant test-call
:
b.call:
b.some-target:
test-call:
[echo] In b.call
BUILD SUCCESSFUL
With the changes to b.ant, the <include>
in a.ant can be simplified by removing the as
attribute:
<include file="b.ant" />
Upvotes: 1
Reputation: 107060
Ant is a dependency matrix specification language. Usually a bunch of <antcall/>
, <ant/>
, <include/>
and <import/>
is a sign of a poorly written build script. It's a developer trying to force Ant to act like a programming language.
For developer, it makes sense to break up a program into smaller files. Even Python and Perl scripts can benefit from this. However, breaking up an Ant build script usually causes problems. We had a developer who went through every project and broke up all the build.xml files into six or seven separate build files in order to improve the process. It basically broke the whole Ant dependency mechanism. To fix it, he then tossed in a bunch of <ant/>
calls and <include>
tasks. In the end, it meant that each target was called between 12 to 20 times.
Not using <import/>
and <antcall/>
isn't a hard and fast rule. But, I've been using Ant for years and rarely ever used these mechanisms. When I do, it's usually for a shared build file that multiple projects will use (which sounds like what you have) but instead of defining targets in my shared build file, I define macros. This eliminates the target namespace issues that you are having, and the macros work better because they act more like Ant tasks. This is especially true with the introduction of <local/>
in Ant 1.8.
See if you can restructure the shared build file into using <macrodef/>
instead of targets. It will make it much easier to include your shared build file.
Upvotes: 2