【问题标题】:Ant - How can I run the same depends from multiple targetsAnt - 我如何运行相同取决于多个目标
【发布时间】:2014-05-08 14:44:08
【问题描述】:

有没有办法让 ant 多次执行多个依赖目标。考虑一下:

<target name="buildall" depends="mycommon,myDAO" />

<target name="myCommon" depends="initCommon, clean, makedir, compile" description="">
    <echo> Build completed for myCommon </echo>
</target>

<target name="myDAO" depends="initDAO, clean, makedir, compile" description="">
    <echo> Build completed for myDao </echo>
</target>

我希望 buildAll 调用 myCommon,它调用 initCommon、clean、makedir、compile,然后调用 myDAO,它调用 initDAO、clean、makedire、compile。

所以我希望多次执行 clean、makedir 和 compile 任务。它们是通用的,根据 initXXX 任务中设置的属性运行。

我试过了:

<target name="buildall">
    <antcall  target="myCommon" />
    <antcall target="myDao" />
</target>

但这每次都运行任务之外的所有内容,这不是我想要的。有什么想法吗?

【问题讨论】:

  • 您所说的“每次都在任务之外”是什么意思?似乎&lt;antcall&gt; 可以按照您的意愿运行目标,但会引入其他问题?
  • 是的 - 我有一堆 任务作为 标记的子项。也许那是错误的。无论我指定多少个目标,这些任务我都想运行一次。
  • 问题是,如果我从 Eclipse 运行并指定多个目标,它只运行 元素一次,它运行每个目标及其每个依赖项(即使依赖项已经之前运行)。当我在 Eclipse 中运行时,一切都很好。当我在 Eclipse 之外运行时,它的工作原理就不一样了。
  • 哦,出现这个问题是因为每次调用&lt;antcall&gt;时,Ant都会为当前的构建文件创建一个新的Project实例。通过这种方式,您可以控制调用目标(及其之前的)中声明的属性和引用是否应该由被调用目标继承——inheritAllinheritRefs。我不使用 Eclipse,所以我不知道它的行为和原因,但你的问题正是纯 Ant 的工作原理。
  • 一个非常非常简单的解决方案:编写自己的 Ant 任务,可能命名为 &lt;runonce&gt;,赋予它运行嵌套 Ant 任务的能力,并在其 execute() 方法中: 1. 检查系统是否财产,例如“冉”,已定; 2.如果设置,则返回;如果没有,运行嵌套任务; 3.设置系统属性“Ran”。

标签: ant


【解决方案1】:

首先:不要使用&lt;antcall/&gt;,这通常表明你做错了。

现在,请了解 Ant 不是一种编程语言,您可以在其中告诉 Ant 您想做什么以及您希望它完成的顺序。 Ant 是一种矩阵依赖语言。你只需告诉 Ant 你想要什么(我想构建这个 jar),然后让 Ant 弄清楚它应该做什么。 Ant 尽最大努力多次运行目标。

例如,myCommonmyDAO 都调用 clean 目标。 Ant 适当地指出,两者都需要clean 目标,然后调用clean 一次且仅一次,然后它才会运行您的两个目标。这就是 Ant 的工作方式。

所以,让 Ant 完成它的工作吧。首先,一般情况下你不应该打扫。构建应该最小化重建以加快任务。如果你没有修改过*.java文件,凭什么逼我重建对应的*.class文件?

第二:不要加倍依赖:例如,如果我想构建目标myDAO,我想编译代码(可能构建一个jar或war)。这就是我的myDAO 目标应该依赖的全部内容。现在,当我编译时,我可能需要创建我的目录,而当我创建我的目录时,我可能需要进行初始化:

<target name="clean">
    <echo>Clean up my working directory to be nice and sparkly</echo>
</target>
<target name="initDAO">
    <echo>Initialize stuff for my DAO build</echo>
    <echo>Maybe setup some properties?</echo>
</target>
<target name="makedir"
     depends="initDAO">
    <echo>I need my directories for building.</echo>
    <echo>But first, I need to setup stuff"</echo>
</target>
<target name="compile"
    depends="makedir">
    <echo>I need to compile my dao source"</echo>
    <echo>But first, I need to make the necessary directories</echo>
<target>
<target name="myDAO"
    depends="compile">
    <echo>Here's where I package up my DAO</echo>
    <echo>But I have to compile stuff before I can package it</echo>
</target>

注意上面的结构。如果我运行目标myDAO,Ant 将查看依赖关系,然后运行initDAOmakedir,编译,最后myDAO 打包所有内容。同样,我有一个clean 目标,它将我的工作空间恢复到原始状态(在构建任何东西之前),但我不将它称为包的一部分,因为我不想重做工作。

“啊!”,你说,“但我必须清理,因为 myCommonmyDAO 使用相同的目录进行构建和打包。”

好吧,不要那样做。相反,请确保您的两个包使用不同的 target 目录进行构建和打包。这样,您不必从一个到另一个清理混乱。而且,您可以更改单个源文件、重新构建,而不必重新编译所有内容。

您可以通过定义macros 来处理两者之间的共同点,从而避免麻烦。例如,您可以定义一个编译宏,将源目录的名称作为其参数,它会根据该源目录名称创建一个 destdir 并编译您的公共目标和DAO 目标。

所以,让 Ant 发挥它的魔力吧。使用依赖关系不是告诉 Ant 如何做某事的一种方式,而只是告诉 Ant 一个特定目标依赖于另一个目标。让 Ant 弄清楚执行的顺序。此外,不要将您的任务设置为要求您清理目录并重新初始化所有内容。您希望 Ant 通过不必重新构建或重新复制未更改的文件来帮助最小化构建。

【讨论】:

  • 很好的答案,antcall 确实是蚂蚁的GOTO
  • 我明白你的意思。我认为诀窍是我的大部分任务(clean、compile、makedir)应该被定义为宏而不是依赖目标。这些任务(clean、compile、makedir)是通用的,并且对 initXXXX 任务中设置的变量进行操作。现在我们可以将它们作为参数传递给宏调用。更好的解决方案。谢谢。
猜你喜欢
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-25
相关资源
最近更新 更多