蚂蚁取决于antcall

时间:2011-05-09 12:34:36

标签: java ant build-process build-automation

在定义顺序构建步骤时,我使用depends元素的target属性。我最近看到了一个ant文件,其中构建序列由目标内的antcall元素定义。 举例说明:

<target name="a" depends="b">
...</target>

VS

<target name="a">
<antcall target="b"/>
...</target>

两种方法之间是否存在真正的差异?其中一个更受欢迎吗?

5 个答案:

答案 0 :(得分:81)

最大的区别是Ant将确保通过depends声明的依赖关系最多被称为一次。例如:

<target name="a" />

<target name="b" depends="a" />

<target name="c" depends="a" />

<target name="d" depends="b, c" />

如果我致电目标d,则会调用bc。但是,a只会被调用一次(即使bc都取决于它)。

现在假设我们决定使用antcall而不是依赖目标d

<target name="d">
   <antcall target="b" />
   <antcall target="c" />
</target>

调用目标d现在会调用目标bc;但是,目标a将被调用两次,一次调用b,然后再调用c

换句话说,antcall回避了作为Ant基石的正常依赖规则。

我认为不应该使用antcall来代替正常的类似Ant的依赖项;这就是depends的用途。所以你什么时候使用它? antcall任务允许您控制定义了哪些属性和引用(这就是创建新Ant环境的原因 - 以及为什么它如此慢),因此它可以用于创建相同内容的变体;例如,可能是两个罐子,一个罐子,一个没有调试符号。

但是,过度使用antcall会导致生成缓慢,脆弱且难以维护的构建脚本。把它想象成蚂蚁的goto - 它是邪恶的。除非在特殊情况下,大多数编写良好的构建脚本根本不需要它。

答案 1 :(得分:55)

两种方法之间的主要区别在于depends中的目标始终执行,而antcall中的目标仅在包含目标时执行。

一个澄清的例子:

<target name="a" depends="b" if="some.flag">

</target>

此处,b将始终执行,而a仅在定义some.flag时执行。

<target name="a" if="some.flag">
    <antcall target="b" />
</target>

此处b只会在a出现时执行,即如果some.flag已定义。

答案 2 :(得分:14)

Antcall相对较少使用,因为:

  

被叫目标以新的方式运行   项目;请注意,这意味着   由...设置的属性,引用等   被叫目标不会持久   到调用项目。

换句话说,antcall是全新隔离的Ant进程运行。

答案 3 :(得分:7)

antcall是蚂蚁的GOTO。这很糟糕。这是制作无法维护的老鼠窝的好方法。在ant-contrib旁边,它是闻到过于复杂难以维护的ant文件的最佳方式。 (即使是一个好的antfile也很粗糙)

如果你的依赖设置得当,你应该能够成功地运行任何目标,这与antcall模式不同。

没有人触及的另一个原因是vizant,如果它是一个复杂的构建,生成目标依赖项图形的能力非常好。如果你使用antcall,你就搞砸了。

我希望@Vladimir Dyuzhev是正确的,很少使用antcall - 我去过很多商店,这是常态。

答案 4 :(得分:0)

  <target name="a" depends="b"> ...</target> 

这意味着在执行任何语句或来自目标a的任何标记之前,ANT确保目标b成功执行

在从调用目标执行某些语句或标记后,您可以使用antcall调用任何目标。