我的构建非常糟糕。最终,目标被执行多达15次。大多数目标被执行了十几次。这是因为构建和目标被划分为10个独立的构建文件(build.xml
、build-base.xml
、compile.xml
等)
在许多构建文件中,在构建文件的所有目标之外,一开始就有<property>
任务。这些通常在调用任何目标之前先执行。
这是我的build.xml
文件:
<import file="build-base.xml"/>
[...]
<target name="compile-base">
<antcall target="setup-tmpj"/>
<ant antfile="compile.xml" target="compile-base"/>
[...]
</target>
这是compile.xml
文件:
<import file="build-base.xml"/>
<property name="target" value="1.5"/>
<available file="target/gensrc/com" property=gensrc.exists"/>
[...]
<target name="buildAndCompileCodeGen" unless=gensrc.exists">
<blah blah blah/>
</target>
<target name="compile-base" depends="buildAndCompileCodeGen">
<blah blah blah/>
</target>
我执行这个:
$ ant -f build.xml compile-base
这将调用compile.xml
文件中的目标compile-base
。这取决于compile.xml
文件中的目标buildAndCompileCodeGen
。然而,只有在属性gensrc.exists
未设置的情况下,才执行目标buildAndCompileCodeGen
。
compile.xml
文件中有一个<available>
任务,它将设置gensrc.exists
属性,但此任务位于compile.xml
中所有目标之外。是否调用过<available>
任务,从而设置了gensrc.exist
?
好吧,我弄清楚发生了什么…
是的,当我通过<ant>
任务调用compile.xml
文件中的compile-base
目标时,在执行目标I调用之前,将执行所有不在目标之下的任务。这意味着,如果代码已经存在,则调用buildAndCompileCodeGen
目标,但不执行。
我所做的是将所有的构建文件合并为一个大文件,并去掉了所有的<ant>
和<antcall>
任务。我已经将<available>
任务放在组合的build.xml
文件中。
在最初的情况下,我将首先执行clean
,然后调用compile.xml
文件中的compile-base
。届时,<available>
任务将运行。由于我进行了清理,文件不存在,属性gencode.exists
没有设置,buildAndCompileCodeGen
目标将运行。
当我组合所有内容时,<available>
任务将运行,设置gencode.exists
属性。然后,当我做clean
时,我会删除生成代码。然而,buildAndCompileCodeGen
目标仍然不会执行,因为已经设置了gencode.exists
。
应该做的是:
<target name="compile-base"
depends="buildAndCompileCodeGen">
<echo>Executing compile-base</echo>
</target>
<target name="buildAndCompileCodeGen"
depends="test.if.gencode.exists"
unless="gencode.exists">
<echo>Executiing buildAndCompileCodeGen</echo>
</target>
<target name="test.if.gencode.exists">
<available file="${basedir}/target/gensrc/com"
property="gencode.exists"/>
</target>
在这种情况下,我调用compile-base
。这将调用buildAndCompileCodeGen
。这将首先调用test.if.gencode.exists
。即使已经设置了属性gencode.exists
,也将执行此操作。在Ant查看if
或unless
参数之前,依赖子句在目标上运行。这样,在准备好执行buildAndCompileCodeGen
目标之前,我不会设置gencode.exists
。现在,可用的任务将在我进行清理后运行。