-
19 January 2010, 18:57
The Basics of Apache Ant
Ant is a great build tool, primarily for Java, though you can easily find (or write) tasks that will do whatever you need. Going beyond the realm of Java is not the intended scope of this post, but will certainly be in scope for future posts. Here, I will cover what Any is, as well as how to run and define your own targets.
Basically, Ant is
makefor Java. It is an external domain specific language (DSL), using an XML-based syntax. Like other build languages, similar to make or rake, the DSL of Ant follows a dependency-based programming model. Different steps in the build process depend on other targets/tasks. Many steps might depend on one target. Now, you wouldn't want to run that same target over and over again, for efficiency reasons. It is my contention that a target should be idempotent--repetitions of an action have no further effect on outcome. Ant will not run the same target twice unless changes are detected, so you have nothing to really worry about.OK so the boring technical stuff is out of the way, let's actually start a project. By default, the Ant executable, which should be on your
PATH, will look in the current directory for a file entitledbuild.xml. You can specify other files to use by using the-fflag. When running Ant on the command line, you can specify which target to execute; we'll get into naming targets soon. For example:ant distorant -f build.xml dist; both are equivalent.The root node of your XML file should look like this:
<project name="YourProject" default="compile"> </project>There are two attributes here of some significance. The first,
name, is simply the name of your project; feel free to make that whatever you want. The second, more significant attribute,default, is which target will be executed when none is given on the command line.The whole point of Ant is to build, so let's build. For this, we need a
target element:<target name="compile" depends="init"> <javac srcdir="src" destdir="bin"/> </target>A target is a container for specific tasks. In the above example, the only task is
javac, which is obviously used for compiling java source files. This target is given the name "compile". Therefore, to run this target from the command line, we would typeant compile.But wait! If you just put that target in the root node and run
ant compile, it won't work! As you can see, that target is dependant on another target namedinit. Here are the relevant targets:<target name="clean"> <delete dir="bin"/> </target> <target name="init" depends="clean"> <mkdir dir="bin"/> </target>Here we have the
inittarget and its dependency, thecleantarget. I threw in aclean, because it's an important target to know how to do, and I wanted to have a more interesting dependency sequence. Builds should generally be incremental, so cleaning before every compile is probably not the best idea. Cleaning before making a distribution build, is a very good idea, since you want to make sure you aren't depending on anything outside of the build process, which should only include things in source control.Now when you run
ant compileorant, it should work for you. You should see thecleanbeing executed, followed byinit, with your desired target,compile, executing last.There's a lot more built into Ant, like the ability to package your compiled files into jars. I couldn't possibly cover every task, and some don't really need to be discussed, like
mkdiranddeleteshown above.To make sure that you have everything as I do, here is the final file that I came up with for this tutorial:
<project name="test" default="compile"> <target name="clean"> <delete dir="bin"/> </target> <target name="init" depends="clean"> <mkdir dir="bin"/> </target> <target name="compile" depends="init"> <javac srcdir="src" destdir="bin"/> </target> </project>