Posts
Search
Contact
Cookies
About
RSS

Anatomy of a simple Ant build.xml file

Added 27 Apr 2017, 11:26 a.m. edited 18 Jun 2023, 7:44 p.m.
I very often start a new Java project by copying over a boiler plate build file, which I thought others might find useful as a quick start. I usually have a minimum of three directories in a project, bin is where the compiled class files go and is in the runtime classpath, lib is where I throw all the jar files I want to use, this is in both the build and runtime classpath and finally the src directory, obviously for anything other than a quick hack then I'd have the package hierarchy reflected in the path for example src/uk/co/bedroomcoders/projectXYZ. If I'm doing something graphical I will often but textures etc in a directory called data just to keep things tidy. File Structure discussed, we can now look at the first part of the build file before discussing the individual targets you can run.
<project name="boilderplate" default="run" basedir=".">
    <description>
        ant build/run file
    </description>

    <!-- the run time classpath is also used to compile -->
    <path id="classpath">
        <pathelement location="bin" />
        <fileset dir="lib" includes="**/*.jar"/>
    </path>
Its actually worth putting in things like a project name and description, as at a later date you can scan the java patch of your development directory and get a set of names and descriptions back, handy for those projects you were doing last year and can't quite remember what they where! I define a classpath that in many cases is fine to use for both run and compile time (although you could have different ones for more complex projects - different client/server projects for example) While not strictly needed there is a clean target
    <!-- removes compiled classes -->
    <target
        name="clean"
        description="cleans the project" >
        <delete>
            <fileset dir="bin" includes="**/*.class" />
        </delete>
     </target>
This might be most useful if you delete a source file for example... notice the use of name and description this is great because you can run ant -p and get a list of all the real targets and a description, something I wish you could do with make.... now comes the largest target
    <target 
        name="compile"
        description="compile the source " >
        <!-- <mkdir dir="bin"/> -->
        <javac 
            destdir="bin"
            includeantruntime="false"
            debug="on"
            debuglevel="lines,vars,source"
        >
            <src path="src" />
            <compilerarg value="-Xlint:all" />
            <compilerarg value="-Werror" />
            <!-- maxerrs param must be seperate or space is picked up as a param -->
            <compilerarg value="-Xmaxerrs" />
            <compilerarg value="1" />
            <!-- <compilerarg value="-Xdiags:verbose" /> -->
            <classpath refid="classpath"/>
        </javac>
    </target>
Odds on you may want to modify this, as I like to see just one error at a time and I also treat warnings as errors :-o ! You can also see a commented out section that allows verbose output, I very rarely seem to need this so its as easy to uncomment it when needed but you could make another almost duplicate target if you wanted. You might also want to make a "release" target that doesn't include debug info.
    <target
        name="run"
        depends="compile"
        description="runs the project compiling if needed" >
        <java
            fork="true"  
            classname="Main"
            classpathref="classpath"
        >
            <!--<jvmarg value="-Djava.library.path=lwjgl/native/" />-->
        </java>
    </target>
The run target is for convenience the default target, but notice it depends on the compile target, this means if you run ant on its own without parameters, then the project will be compiled, and if there are no errors it will then be run. There is also and example of setting java "system" property, although this particular one is now defunct, and only kept as a reminder of how a system property is set. And finally for the lazy I even get ant to load the sources into my favourite editor...
    <target
        name="edit"
        description="loads all source into an editor" >

        <exec executable="/bin/bash" spawn="true"> <!-- to allow wild card expansion -->
            <arg value="-c"/>
            <arg value="geany -i src/*"/>
        </exec>
    </target>
As you can see there isn't anything intrinsically difficult with Ant, and thankfully its considerably better documented than some projects, so taking things further and modifying it for your own convenience shouldn't be too difficult. here's the complete boiler plate Ant build script.