I am using apache ant as follows:
I have projects P1, P2, P3. Some of these projects have modules, let P2 have M1, M2, etc. All projects have their own ant build script, and all of them must implement a set of predefined goals (build, dist, etc.). Scripts expect some properties to be defined upon invocation. let's say (build.dir.base)
Modules follow a similar structure, so each module has its own build file, which implements a predefined set of goals and expects some properties to be set. (let's say build.dir.base is the same as for projects)
I also have a global ant script that builds all projects (or a subset)
In the code that will look like this:
built-in 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 (one for each project with modules, subant if the project does not have modules):
<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>
And for projects with modules: build.xml (for the module):
<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>
This structure allows you to build projects independently of each other, as well as modules can be built independently or the entire system can be built using build-all.xml. In addition, the final product has the following structure:
- $ {system.build.base} / P1,
- $ {system.build.base} / P2 / M1
- $ {system.build.base} / P2 / M2
etc.
However, since ant> = 1.8.0, this is no longer possible. The reason is that <property name="build.dir.base" location="${basedir}/build" /> in build-all.xml takes precedence over <property name="build.dir.base" location="${build.dir.base}/${name}" /> in build.xml (build for projects). Thus, the purpose of the submodules project is in ${system.build.base}/M1 instead of ${system.build.base}/P2/M1
This is because Properties defined on the command line cannot be overridden by nested elements. Since ant 1.8.0. the same is true for nested task structures: if the assembly file A calls B through the task definition, the property with the nested element and B contains the tasks that call C, C will see the value set to A, even if B used the nested one.
It is not possible to override a property for subant if some of the parents have also defined this property. This is very difficult since the assembly must be aware of the properties that the parent used for some unrelated reason.
Is there a workaround for this incompatible behavior change? Since my build system is heavily dependent on <subant inheritAll="false" inheritRefs="false"> to execute exec without polluting the substrings.