Ant:如何测试目标是否存在(如果不存在则调用它)?

时间:2011-05-26 17:52:41

标签: ant conditional target antcall

我有一组构建文件,其中一些调用其他文件 - 首先导入它们。行结束可能具有或不具有特定目标(例如“复制”)。如果该目标是在行尾构建脚本中定义的,我想从我的主构建文件中调用它。我该怎么办?

调用脚本的一部分:

<!-- Import project-specific libraries and classpath -->
<property name="build.dir" value="${projectDir}/build"/>
<import file="${build.dir}/build_libs.xml"/>

...

<!-- "copyother" is a foreign target, imported in build_libs.xml per project -->
<target name="pre-package" depends="    clean,
                                        init,
                                        compile-src,
                                        copy-src-resources,
                                        copy-app-resources,
                                        copyother,
                                        compile-tests,
                                        run-junit-tests"/>

我不希望每个项目都定义“copyother”目标。我怎样才能进行有条件的蚂蚁电话?

3 个答案:

答案 0 :(得分:3)

我猜你没有将“其他”构建脚本导入主build.xml。 (因为那不起作用.Ant将进口视为本地。)

与此同时,你正在使用依赖而不是蚂蚁/蚂蚁呼叫,所以也许你正在导入它们,但一次只能进行一次。

你无法在原生Ant中做你想做的事。正如您所说,对文件的测试很容易,但目标不是。特别是如果尚未加载其他项目。你必须编写一个自定义Ant任务来完成你想要的任务。两个途径:

1)调用project.getTargets()并查看您的目标是否存在。这包括重构你的脚本以使用ant / antcall而不是pure depends,但不会感觉像是hack。编写自定义Java条件并不难,Ant手册中有一个示例。

2)将目标添加到当前项目(如果尚未存在)。新目标将是无操作。 [不确定这种方法是否有效]

答案 1 :(得分:1)

同样的完整性。另一种方法是有一些目标来检查目标。

这里讨论的方法是:http://ant.1045680.n5.nabble.com/Checking-if-a-Target-Exists-td4960861.html(vimil的帖子)。使用scriptdef完成检查。所以它与其他答案(Jeanne Boyarsky)没有什么不同,但脚本很容易添加。

<scriptdef name="hastarget" language="javascript">
    <attribute name="targetname"/>
    <attribute name="property"/>
    <![CDATA[
       var targetname = attributes.get("property");
       if(project.getTargets().containsKey(targetname)) {
            project.setProperty(attributes.get("property"), "true");
       }
     ]]>
</scriptdef>

<target name="check-and-call-exports">
    <hastarget targetname="exports" property="is-export-defined"/>
    <if>
        <isset property="is-export-defined"/>
        <then>
            <antcall target="exports"   if="is-export-defined"/>
        </then>
    </if>
</target>

<target name="target-that-may-run-exports-if-available" depends="check-and-call-exports">

答案 2 :(得分:0)

您应该探索使用typefound条件,在1.7中添加到ANT。例如,您可以使用antcontrib中的if任务,但是由于它的工作方式,您必须检查macrodef而不是taskdef:

<if>
   <typefound name="some-macrodef"/>
<then>
   <some-macrodef/>
   </then>
</if>

有了这个,有一个名为“some-macro-or-taskdef”的macrodef的ant文件将被调用,而没有它的其他ant文件将不会出错。