我想使用manifestclasspath
Ant任务。我有一个非常大的build.xml文件和几个导入的其他构建文件,当我运行它时,我得到的是:
build.xml:1289: The following error occurred while executing this line:
build.xml:165: Property 'some.property' already set!
我确信此属性仅在manifestclasspath
任务中定义。这是我的代码:
<manifestclasspath property="some.property" jarfile="some.jar">
<classpath refid="some.classpath"/>
</manifestclasspath>
此代码位于<project>
内部。
我做错了什么?是否有一种方法可以在尚未设置属性的情况下添加类似condition
的内容来设置属性?如果有其他方法的话,我不想使用自定义Ant任务,比如Ant-Contrib的if
。
Antcall打开一个新的项目范围,但默认情况下,当前项目的所有属性都将在新项目中可用。如果你使用类似=的东西
<antcall target="whatever">
<param name="some.property" value="somevalue"/>
</antcall>
在调用项目中,${some.property}也已经设置好了,不会被覆盖,因为一旦设置好属性,ant中的属性在设计上是不可变的。或者,您可以将inheritAll属性设置为false,并且只有"用户"属性(在命令行上以-Dproperty=value传递的属性)将传递给新项目。因此,当${some.properties}不是用户属性时,使用inheritAll="false"就完成了。
顺便说一句。通过dependens="…"属性使用目标之间的依赖关系比使用antcall更好,因为它打开了一个新的项目范围,并且在新项目中设置的属性不会返回到调用目标,因为它位于另一个项目范围中。。
在一个片段之后,请注意区别,首先没有inheritAll属性
<project default="foo">
<target name="foo">
<property name="name" value="value1" />
<antcall target="bar"/>
</target>
<target name="bar">
<property name="name" value="value2" />
<echo>$${name} = ${name}</echo>
</target>
</project>
输出:
[echo] ${name} = value1
inheritAll为false的第二个
<project default="foo">
<target name="foo">
<property name="name" value="value1" />
<antcall target="bar" inheritAll="false" />
</target>
<target name="bar">
<property name="name" value="value2" />
<echo>$${name} = ${name}</echo>
</target>
</project>
输出:
[echo] ${name} = value2
antcall的一些经验法则,它很少被使用是有充分理由的:
1.它打开了一个新的项目范围(启动一个新"ant-buildfile yourfile.xml yourtarget")
因此它使用了更多的内存,降低了构建速度
2.被调用目标的依赖目标也将被调用
3.属性不会传递回调用目标
在某些情况下,用不同的参数调用同一个"独立"目标(一个没有依赖目标的目标)以供重用可能没问题。通常使用macrodef或scriptdef。因此,在使用antcall之前要三思而后行,这也会给脚本带来多余的复杂性,因为它会违反正常的流程
回答评论中的问题,使用依赖关系图而不是ant调用
您有一些目标,它包含所有条件并设置适当的属性,这些属性可以由目标通过if和excess属性进行评估,以控制进一步的流
<project default="main">
<target name="some.target">
<echo>starting..</echo>
</target>
<!-- checking requirements.. -->
<target name="this.target">
<condition property="windowsbuild">
<os family="windows"/>
</condition>
<condition property="windowsbuild">
<os family="unix"/>
</condition>
<!-- ... -->
</target>
<!-- alternatively
<target name="yet.another.target" depends="this.target" if="unixbuild">
-->
<target name="another.target" depends="this.target" unless="windowsbuild">
<!-- your unixspecific stuff goes here .. -->
</target>
<!-- alternatively
<target name="yet.another.target" depends="this.target" if="windowsbuild">
-->
<target name="yet.another.target" depends="this.target" unless="unixbuild">
<!-- your windowspecific stuff goes here .. -->
</target>