我正在以下列方式使用apache ant:
我有项目P1,P2,P3。其中一些项目有模块,比方说P2有M1,M2等。 所有项目都有自己的ant构建脚本,并且所有项目都必须实现一组预定义目标(build,dist等),脚本期望在调用时定义一些属性。让我们说(build.dir.base)
模块遵循类似的结构,因此每个模块都有自己的构建文件来实现预定义的目标集,并期望设置一些属性。 (比如build.dir.base - 与项目相同)
我还有一个构建所有项目(或子集)的全局ant脚本
在代码中看起来像:
积all.xml:
<project name="x">
<property name="build.dir.base" location="system.build.base" />
<target name="build">
<echo message="build.dir.base as defined for build-all.xml=${build.dir.base}" />
<subant antfile="build.xml" target="build" inheritAll="false" inheritRefs="false">
<dirset dir="${system.base}" includes="${project-list}" />
<property name="build.dir.base" location="${build.dir.base}" />
</subant>
</target>
</project>
build.xml(每个带有模块的项目一个,如果项目没有模块,则没有subant
):
<project name="y">
<property name="build.dir" location="${basedir}/build" />
<target name="build">
<echo message="build.dir.base as defined for project=${build.dir.base}" />
<subant antfile="build.xml" target="build" inheritAll="false" inheritRefs="false">
<dirset dir="project.base" includes="${module-list}" />
<property name="build.dir.base" location="${build.dir.base}/${name}" />
</subant>
</target>
</project>
对于有模块的项目: build.xml(用于模块):
<project name="z">
<property name="build.dir.base" location="build.dir.base" />
<target name="build">
<echo message="build.dir.base as defined for module=${build.dir.base}" />
</target>
</project>
此结构允许独立构建项目,也可以独立构建模块,也可以使用build-all.xml构建整个系统。 此外,最终产品具有以下结构:
等
然而,由于ant> = 1.8.0,因此不再可能。原因是
build-all.xml中的<property name="build.dir.base" location="${basedir}/build" />
在build.xml(项目构建)中优先于<property name="build.dir.base" location="${build.dir.base}/${name}" />
。因此,项目“子模块”的目标位于${system.build.base}/M1
而不是${system.build.base}/P2/M1
如果某些父母也定义了该属性,则无法覆盖subant
的属性。这很严重,因为构建应该知道父级用于某些无关原因的属性。
这种不兼容的行为更改是否存在解决方法?因为,我的构建系统在很大程度上依赖于<subant inheritAll="false" inheritRefs="false">
将执行exec而不污染子构建的事实。
答案 0 :(得分:1)
不是一个完整的答案,但我发现你可以通过执行以下操作来阻止子任务继承特定属性:
<resources id='aoeu'>
<intersect>
<propertyset>
<propertyref builtin="commandline"/>
</propertyset>
<propertyset negate="true">
<propertyref name="property.not.to.be.inherited"/>
</propertyset>
</intersect>
</resources>
<groovy>
ant.propertyset(id:"snth") {
project.references["aoeu"].each {
propertyref(name:"${it.name}")
}
}
</groovy>
<subant buildpathref="buildpath">
<propertyset>
<propertyset refid="snth"/>
</propertyset>
<target name="zvwm"/>
</subant>
答案 1 :(得分:1)
https://issues.apache.org/bugzilla/show_bug.cgi?id=49891似乎也与这个问题有关。
在尝试了许多不同的东西(包括过滤掉不需要的属性然后重置它的技术)后,我得出结论,在子任务中覆盖命令行属性是不可能的。
答案 2 :(得分:0)
这不是不可能!!您可以使用scriptdef覆盖属性 self.getProject()。setInheritedProperty(键,值)。看看API
答案 3 :(得分:0)
您可以使用antcontrib var任务。 http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html