To achieve complete independance from the language and tools used for a project, the build stage of the autobuild cycle is considered a black box. To perform the build, autobuild merely invokes an opaque control file provided by the developer. This shell script will typically perform four tasks - configure, build, install and package. The autobuild will capture the standard output and error streams, saving to the modules build log files. In common with standard UNIX behaviour, an exit status of zero indicates a successful build, while non-zero indicates failure.

Environment variables

When the control file is invoked, a number of environment variables will be set in its shell. In versions 1.0.x, there are two environment variables.

AUTO_BUILD_ROOT
The path to a virtual root directory where software should be installed. When a module is built, it is guarenteed that the installed files from any dependant modules will be present in this directory. This enables a module to depend on the output of another module. The contents of this directory, however, are not preserved across runs of the build.
AUTO_BUILD_COUNTER
A counter identifying the current run of the build. Typically this will be the number of seconds since the UNIX at the time the current build cycle began, but may alternatively be a version control changelist.

In the 1.1.x series, these two are deprecated (but still available) in favour of an expanded set

AUTOBUILD_MODULE
The name of the module which is being built
AUTOBUILD_INSTALL_ROOT
The path to a virtual root directory where software should be installed. When a module is built, it is guarenteed that the installed files from any dependant modules will be present in this directory. This enables a module to depend on the output of another module. The contents of this directory, however, are not preserved across runs of the build.
AUTOBUILD_PACKAGE_ROOT
The path to a directory in which a module's build process will create any binary packages it generates, for example RPMs, or Debian packages. The packages are typically placed into a package type specific sub-directory.Consider, for example, a module which generates an RPM, of itself. The $AUTOBUILD_PACKAGE_ROOT directory would be used to set the '_topdir' macro for the RPM build process
  rpmbuild --define '_topdir $AUTOBUILD_PACKAGE_ROOT/rpm' -ta foo.tar.gz
AUTOBUILD_SOURCE_ROOT
The path to the directory in which modules are checked out. This can be used in conjunction with $AUTOBUILD_MODULE to identify the root directory for the module
AUTOBUILD_COUNTER
A counter identifying the current run of the build. Typically this will be the number of seconds since the UNIX at the time the current build cycle began, but may alternatively be a version control changelist.
AUTOBUILD_TIMESTAMP
A counter identifying the timestamp taken at the start of the build cycle. When checking out code, all version control systems are synchronized to no later than this timestamp. For a given value of $AUTOBUILD_TIMESTAMP the source code being built will always be identical, thus this is suitable for use as a unique identifier for a build.

Integrating with Perl (ExtUtils::MakeMaker)

All Perl modules which use ExtUtils::MakeMaker for their build and install process can use the same pattern for their control file. The key to this pattern is to set the value for the PREFIX variable to $AUTO_BUILD_PREFIX when running the Makefile.PL script:

perl Makefile.PL PREFIX=$AUTOBUILD_INSTALL_ROOT

Any non-trivial Perl module will likely have dependancies on other modules built and installed earlier in the cycle. To enable MakeMaker's pre-requisite checking to pick these up, it is neccessary to set the PERL5LIB environment variable to point to the virtual install root containing the site specific modules:

PERL5LIB=$AUTOBUILD_INSTALL_ROOT/lib/perl5/site_perl/5.8.0

Hard coding the site_perl in this way is not very good practice, however, since the same code (and thus control file) may be used across many autobuild instances with differing versions of Perl installed. The solution is to make use of the standard Config module to extract the location.

PERL5LIB=`perl -e 'use Config; my $dir = $Config{sitelib}; \
  $dir =~ s|/usr|$ENV{AUTOBUILD_INSTALL_ROOT}|; print $dir'`

To a complete script to configure, build, install the module and create a source code distribution would look like:

#!/bin/sh

set -e

# Pull in prerequisite modules
PERL5LIB=`perl -e 'use Config; my $dir = $Config{sitelib}; \
  $dir =~ s|/usr|$ENV{AUTOBUILD_INSTALL_ROOT}|; print $dir'`
export PERL5LIB

# Clean up build area
[ -f Makefile ] && make -k realclean ||:
rm -rf MANIFEST blib

# Configure the build
perl Makefile.PL PREFIX=$AUTOBUILD_INSTALL_ROOT

# Make & install 
make
make install

# Create source code dist
make dist

Integrating with C & C++ (AutoConf / AutoMake)

With a few notable exceptions (Perl & Apache), C and C++ programmers have been increasingly converging on GNU Auto Tools for configuring and building their software. As with MakeMaker, the key task is to set the installation prefix when running the configure script:

./configure --prefix=$AUTOBUILD_INSTALL_ROOT

The task of resolving inter-module build dependancies is somewhat less well defined. There are a number of approaches that may work - some programs may even need a combination of all of them!

Configuration helper program

Some libraries install a small shell script to the bin directory that programs can use to determine the correct compiler and linker flags. For example, the gtk-config script can print out the compiler flags required when building against GTK. These scripts are typically generated at build time based on the values to the configure script. Thus it is sufficient to add the bin directory containing this script to the PATH environment variable:

PATH=$AUTOBUILD_INSTALL_ROOT/bin:$PATH

Configure script options

Another common approach to locating pre-requisite libraries is for the program's configure script to have command line options for specifying include and library search paths. For example, when building the Resin Java servlet container, the configure script has --with-openssl-lib and --with-openssl-include options. Thus when configuring Resin, as well as setting the prefix, we'd set these two options:

./configure --prefix=$AUTOBUILD_INSTALL_ROOT \
  --with-openssl-lib=$AUTOBUILD_INSTALL_ROOT/lib
  --with-openssl-include=$AUTOBUILD_INSTALL_ROOT/include

An alternative to specifying both library and include search paths is to just tell the configure script the installation prefix of the library:

./configure --prefix=$AUTOBUILD_INSTALL_ROOT \
  --with-openssl=$AUTOBUILD_INSTALL_ROOT

Compiler environment variables

If there is no explicit support for specifying the location of pre-requisite libraries then the final approach is to try setting compiler environment variables. The two important ones being CFLAGS and LDFLAGS:

CFLAGS=-I$AUTOBUILD_INSTALL_ROOT/include
LDFLAGS=-L$AUTOBUILD_INSTALL_ROOT/lib

Now a complete example control file might look like

#!/bin/sh

set -e

# Pull in config scripts
PATH=$AUTOBUILD_INSTALL_ROOT/bin:$PATH
export PATH

# Clean up build area
[ -f Makefile ] && make -k maintainer-clean ||:

# Re-generate autotools scripts
autoconf
automake -a

# Configure the build
./configure --prefix=$AUTOBUILD_INSTALL_ROOT \
  --with-openssl=$AUTOBUILD_INSTALL_ROOT

# Make & install 
make
make install

# Create source code dist
make dist

Integrating with Java (ANT)

When it comes to writing build.xml files for Java programs with ANT, pretty much anything goes. Fortunately, most of the time there are only two things to worry about, firstly where/how any pre-requisite JARs are located/found, and secondly where to put any generated JARs. For Linux systems, JPackage has been pushing standardization efforts towards a central repository in /usr/share/java, with the alternatives program being used to manage concurrent, differing versions. Thus the first step when creating a Java program is to get the pre-requisite libraries into the ClassPath. The simplest way is to have a bunch of lines such as:

CLASSPATH=$CLASSPATH:$AUTOBUILD_INSTALL_ROOT/share/java/[somepackage].jar

Some ANT build.xml files may have a property for specifying the location of libraries which can be set for compilation

ant -Dlibrary.dir=$AUTOBUILD_INSTALL_ROOT/share/java build

Very few ANT build.xml files concern themselves with installation of JARs, however, it is pretty simple to use the standard UNIX install program from the control file:

install -D mylib.jar $AUTOBUILD_INSTALL_ROOT/share/java/mylib.jar

So a complete control file for a Java program might look like

#!/bin/sh

ant -Dlibrary.dir=$AUTOBUILD_INSTALL_ROOT/share/java build

install -D mylib.jar $AUTOBUILD_INSTALL_ROOT/share/java/mylib.jar