Ant Tip 1: Write a master build file

Many Java projects are divided into multiple subprojects or modules, each in its own directory. Often you’ll want to build subprojects individually, without necessarily building all of the larger master project. For example, in my XOM project, I have one master build.xml file that builds the software itself, and another build.xml file in the web directory that builds the web site. jEdit is divided into separate jedit, jeditshell, macros, and plugins directories, each of which has its own build.xml file.

Furthermore, projects may have dependencies on other projects. For instance XOM 1.1, JDOM, and dom4j all depend on Jaxen. For the latest and greatest JAR, Jaxen should be rebuilt using its own build.xml file, rather than bundling a stale JAR archive that’s months or even years beyond its expiration date.

You could cd into each separate diretory and type ant compile in each one, but that’s time conmsuming and error prone. Plus interproject dependencies may require this to be done in a precise order that makes this even more error-prone. It’s preferable to create a master build file at the top level that compiles everything by invoking targets in the other build files. The ant task lets you do this. For example, this task executes the build.xml file in the directory website (relative to the directory where the current build.xml file is) :

  <target name="website" depends="init" description="Build the website">
    <ant dir="website">
  </target>

If the build file is named anything other than build.xml, add an antfile attribute giving the file name:

  <target name="website" depends="init" description="Build the website">
    <ant antfile="docbuild.xml" dir="website">
  </target>

Both of these execute the default target. You can select a different target using the target attribute like this:

  <target name="website" depends="init"
       description="Build the website">
    <ant antfile="build.xml" dir="website" target="tutorial">
  </target>

By default, all Ant properties in effect for the current target are passed to the subbuild. You can prevent this by setting inheritAll to false:

  <target name="website" depends="init" 
      description="Build the website">
    <ant antfile="build.xml" dir="website" inheritAll="false" >
  </target>

If you set inheritAll to false, you can still pass individual properties to the subbuild using using nested property elements. These can use either the same or different property values. You can also set new properties for the subbuild that are not available in the master build. For example, this task inherits the version property, changes the license property to the fixed value Commons Attribution-NonCommercial-NoDerivs, and removes all other properties:

  <target name="website" depends="init" 
        description="Build the website">
    <ant antfile="build.xml" dir="website" inheritAll="false" />
    <property name="version" value="${version}"/>
    <property name="license" 
                     value="Commons Attribution-NonCommercial-NoDerivs "/>
  </target>

That’s pretty much it. You can now have separate build files for different reasons and still combine them all. Cool!

8 Responses to “Ant Tip 1: Write a master build file”

  1. jake Says:

    I wanted to know is is it possible to explain what these symbols mean ${

  2. The Snake Roberts Says:

    maybe you should check out this website it has alot of stuff on ANT
    http://ant.apache.org/svn.html

  3. John Cowan Says:

    See the classic paper “Recursive make Considered Harmful (abstract, PDF) for more on why launching recursive makes in subdirectories is a dangerous anti-pattern.

  4. Subhas Says:

    D:\WORKING\springapp>ant build
    Buildfile: build.xml

    build:
    [javac] Compiling 7 source files to D:\WORKING\springapp\war\WEB-INF\classes
    BUILD FAILED
    D:\WORKING\springapp\build.xml:42: C:\Sun omcat-lnp\common\lib not found.
    What was the Problem.
    Please Help Me.

  5. Rasmus Says:

    The problem is that on line 42 in the D:\WORKING\springapp\build.xml file you are referring to a directory that does not exist namely C:\Sun omcat-lnp\common\lib

    ๐Ÿ˜‰

    Should kinda be obvious!

  6. Polskietorentypl Says:

    I used to be very happy to find this web-site.I wished to thanks on your time for this glorious learn!! I positively having fun with every little little bit of it and I’ve you bookmarked to take a look at new stuff you weblog post.

  7. Szkolenia Says:

    Wow, amazing blog layout! How long have you been blogging for? you made blogging look easy. The overall look of your web site is magnificent, let alone the content! Regards, Szkolenia.

  8. JimS. Says:

    Great Resource, even 6 years later – Thanks!

    I found (using Ant v1.8.4, at least) that if I’m passing properties to the child build file, I need to surround the properties with the tags, such as . This may be considered an anti-pattern for large/complex projects, but for reasonably-sized efforts, this is a real lifesaver!