在定义顺序构建步骤时,我使用depends
元素的target
属性。我最近看到了一个ant文件,其中构建序列由目标内的antcall
元素定义。
举例说明:
<target name="a" depends="b">
...</target>
VS
<target name="a">
<antcall target="b"/>
...</target>
两种方法之间是否存在真正的差异?其中一个更受欢迎吗?
答案 0 :(得分:81)
最大的区别是Ant将确保通过depends
声明的依赖关系最多被称为一次。例如:
<target name="a" />
<target name="b" depends="a" />
<target name="c" depends="a" />
<target name="d" depends="b, c" />
如果我致电目标d
,则会调用b
和c
。但是,a
只会被调用一次(即使b
和c
都取决于它)。
现在假设我们决定使用antcall
而不是依赖目标d
:
<target name="d">
<antcall target="b" />
<antcall target="c" />
</target>
调用目标d
现在会调用目标b
和c
;但是,目标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调用任何目标。