antbuildbuild-processbuild-automationbuild-environment

ant large project. How to enforce common output directory structure - include,import and inhertAll=false?


I have a toplevel ant project and many subprojects under it.

./build.xml
./datamodel_src/src/build.xml
./datamodel_src/src/module1/build.xml
./datamodel_src/src/module2/build.xml
./infrastructure_src/src/build.xml
./interfaces_src/src/build.xml

Each of the subproject, I want to enforce a common output directory structure. Project will have a work area and each sub project will have its own work area under it. Each subproject should create its artifacts (lib, docs, classes etc) under a work area for the subproject.

So the output would be some thing like

c:/sandbox/mainprojectworkarea/subprojectworkarea/lib
c:/sandbox/mainprojectworkarea/subprojectworkarea/docs
c:/sandbox/mainprojectworkarea/subprojectworkarea/classes

Currently I do this as follows.

The toplevel build.xml is like below

<project name="toplevelproject" default="compile" basedir=".">
    <target name="compile">
        <ant dir="infrastructure_src/src" />
        <ant dir="interfaces_src/src " /> <!--does not work-->
        <ant dir="datamodel_src/src inhertAll=false" /> <!--works-->
    </target>
</project>

common.xml is like below

<property environment="env" />
<property name="project.sandbox" value="${env.BUILD_HOME}/sandbox" />
<property name="sandbox"  value="${project.sandbox}" />
<property name="pwa"  value="${sandbox}/pwa" />
<property name="wa"  value="${pwa}/${ant.project.name}" />
<property name="build"  value="${wa}/build" />
<property name="lib"  value="${wa}/lib" />
<property name="docs"  value="${wa}/docs" />
<property name="exports"  value="${wa}/exports" />

This is "included" into all projects. For example "datamodel_src/src/build.xml" is like below

<!DOCTYPE project [
       <!ENTITY common SYSTEM "../../common.xml">
]>

<project name="dmodel" default="compile" basedir=".">
    &common;
    <target name="compile">
        <echo  message="will create lib  in  ${lib}"/>
        <echo  message="will create docs  in  ${docs}"/>
        <ant dir="module1" inheritAll="false"/> <!--works fine-->
        <ant dir="module2" /> <!--does not work -->
    </target>   
</project>

This works when I set inhertiAll=false for ant calls.

Is there a better and correct way to?

Expanding answer from Kevin to this question. Using import the common.xml becomes a real project like below

<project name="toplevelproject" default="compile" basedir=".">
    <property name="toplevel" value="settotrue"/>
    <target name="compile">
        <ant dir="infrastructure_src/src" />
        <ant dir="interfaces_src/src" />
        <ant dir="datamodel_src/src" />
    </target>
</project>

The "datamodel_src/src/build.xml" is now some think like below.

<project name="dmodel" default="compile" basedir=".">
    <import file="../../common.xml" />
    <target name="compile">
        <echo  message="will create classes in  ${build}"/>
        <echo  message="will create lib  in  ${lib}"/>
        <ant dir="module1" inheritAll="false"/> <!--works fine-->
        <ant dir="module2" /> <!--does not work -->
    </target>
</project>

The import gives option to have common targets etc, hence I would go with it.


Solution

  • I'm doing something similar using imports rather than includes. All my common targets and properties are defined in a common build file and each subproject just imports the common file. When you import a file, the properties defined in that file become relative to the importing file.

    So I would try doing the following:

    1. Move your compile target from your subproject build files into your common.xml.

    2. Import your common.xml into each subproject build.xml.