A guide to Ant, an advanced build system
Jump to navigation
Jump to search
Ant is a very advanced and flexible build system. It seems really modular and able to accomplish a lot of tasks. However, it also seems complex to understand and learn.
The Basics
- Ant build files are XML files.
- These XML buildfiles (default name, like "Makefile" for GNU Make, is "build.xml") contain a list of targets. A target itself contains a list of tasks.
- A task is anything Ant can do: it can launch a Java compilation, copy files to a directory, and LOTS of other stuff.
Ant and Gentoo
- On Gentoo, Ant uses the ANT_TASKS environment variable. This will create a default system classpath. Be cautious about this classpath: it may include some versions of jars you don't want to use. To disable the default system classpath, use ANT_TASKS="none".
Hints & Tips
- To import another file from a first one, you can use the import task:
<import file="configuration.ant.xml"/>
In this case, the imported file must be a valid Ant XML file. You can also (more easily) just include a list of properties from a file directly with the property task.
- To be able to reference a variable and expand it (eg, for ${DeploymentDirectory} to be replaced by /var/www/), you must use a property (here, with the name "DeploymentDirectory"). It won't work if you try to reference an XML node, for example.
- In the javac task, don't include part of the package structure in the srcdir attribute. Eg, don't write srcdir=src/com/example/. Else it will confuse Ant, and Ant will rebuild every Java source file at every run.
- To echo a path or file set, create a property and use the refid attribute, pointing to the file set. Then echo the property.
<fileset id="modified" dir="template"> <svnModified/> </fileset> <property name="modified.files" refid="modified"/> <echo message="${modified.files}" />
- You can build path structures containing file sets very easily with nested fileset nodes.
<path id="hosted.class.path"> <pathelement path="${java.class.path}/" /> <fileset dir="/usr/share/tomcat-5.5/common/lib" casesensitive="yes"> <include name="**/*.jar" /> </fileset>
- To use special characters like " (quotes) in Ant, use the HTML/XHTML special representations (").
- To print Ant's class path from the command line:
ant --execdebug
Data Structures
File Sets
- When invoking a task involving file sets (delete for example), and you want to also include empty directories, don't forget to add the includeemptydirs="true" attribute.
- Pay attention to nested elements in file sets. For example, if you want all *.xml files, but not *.cfg.xml files, use:
<fileset dir="src/" includes="**/*.xml" > <exclude name="**/*.gwt.xml"/> </fileset>
The following would not work:
<fileset dir="src/" includes="**/*.xml" /> <fileset dir="src/" excludes="**/*.gwt.xml"/>
- As a nested element, include cannot contain a comma separated list. This is only valid when used as an attribute.
Resource Collections
- Resource collections were introduced in Ant 1.7.0. They are a modern version of filesets, for example, they allow filesets to be merged (via the union element), and probably lots of useful other stuff. Unfortunately, not many tasks can make use of them currently. In these cases, you have to resort to the old filesets.
Paths
- Note that paths represent just this (paths). As a result you cannot copy files using a pathlike structure; it would recognize absolute paths as such and would copy the file to its original location (so would not do anything).
Tasks
- The scp task does not seem to work with directories containing subdirectories (the scp operation will hang). Update: this was due to a bug introduced in jsch 0.1.30 (the library Ant uses for SSH communication). Update to jsch 0.1.32 and a recent ant-jsch.
- There seems to be a very interesting Subversion task (svnant, developed at Tigris) which allows you to do operations based on file selectors. You could then define a fileset with all modified files, for example.
- The tar task does not preserve file permissions (the GNU tar program does). This is because Java does not offer an API to fetch the permissions on a file. The Ant tar task still offers a way of setting the permissions explicitly if you need to.
- The copy task does not allow you to use nested file elements, even if you nest those in a resources elements. This is probably a bug. You can use filesets representing only one single file instead (this works with absolute paths).
Gant
Gant seems to be a really excellent build system. It is a combination of Groovy code and Ant tasks. Quick notes about Gant:
- ${root.property} WILL not refer to an Ant property in a Gant script, but (logically) to a Groovy variable. Access an Ant property in the following way:
Ant.antProject.properties."root.property"
Set it using:
Ant.property(name: "local.deployment.dir", value: "/var/lib/tomcat-5.5/webapps/")