我用以下方式使用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>
Run Code Online (Sandbox Code Playgroud)
build.xml(每个带有模块的项目一个,subant
如果项目没有模块,则为no ):
<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>
Run Code Online (Sandbox Code Playgroud)
对于具有模块的项目: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>
Run Code Online (Sandbox Code Playgroud)
这种结构允许独立构建项目,也可以独立构建模块,也可以使用build-all.xml构建整个系统.此外,最终产品具有以下结构:
等等
但是,由于ant> = 1.8.0,这是不可能的.原因是
<property name="build.dir.base" location="${basedir}/build" />
build-all.xml优先<property name="build.dir.base" location="${build.dir.base}/${name}" />
于build.xml(为项目构建).因此,项目"子模块"的目的地是${system.build.base}/M1
代替${system.build.base}/P2/M1
subant
如果某些父级也定义了该属性,则无法覆盖属性.这很严重,因为构建应该知道父级出于某些不相关的原因使用的属性.
这种不兼容的行为变化是否有解决方法?因为,我的构建系统在很大程度上依赖于<subant inheritAll="false" inheritRefs="false">
执行exec而不会污染子构建的事实.
https://issues.apache.org/bugzilla/show_bug.cgi?id=49891似乎也与这个问题相关。
在尝试了许多不同的方法(包括过滤掉不需要的属性然后重置它的技术)之后,我得出的结论是,不可能在子任务中覆盖命令行属性。