====== Autotools nano-HOWTO ====== [[http://juha.vierinen.net/files/autotools-nano-howto.html]] (c) 2005,2007 Juha Vierinen jPARSE@THISsgo.fi ===== Introduction ===== One often gets a warm fuzzy feeling seeing the autoconf generated configure file after unpacking a source tarball -- this is because your chances of easily compiling the piece of software have grown significantly. This doesn't mean that you won't have any problems -- you will have problems with compiling software sooner or later -- it just means that things tend to go more smoothly when autoconf and automake (referred to as autotools in this text) are involved. The main purpose of these tools is ease the pain of compiling software on different platforms, but automake can additionally automate many other aspects of software configuration management.

===== Building autotools managed software ===== The end user never needs to use autoconf or automake, as these tools create a plain vanilla sh script called ''configure''. This way the platform used for compiling doesn't need to have a working autotools, just a regular bourne shell. The normal way to proceed after untarring a source package is this: ./configure ; make ; make install Usually there are also many custom options provided by the package maintainer. The help option usually lists these. ./configure --help For example, --prefix will install the software into the home directory of the user instead of the default location (/usr or /usr/local). ./configure --prefix=/home/user Common environment variables are ''CFLAGS, CXXFLAGS, FFLAGS, FCFLAGS, LIBS'' and ''LDFLAGS''. These are processed and tested by configure and added to the flags that configure comes up with. On more obscure (e.g., AIX) platforms, you will often have to come up with ''CFLAGS'' and ''LDFLAGS'' that will find the right headers and libraries. For example: > export CFLAGS="-O42 -g --funny-compiler-flag -I/hard/to/guess/directory" > ./configure ; make # will usually use your CFLAGS for compiling Sometimes, a package might also include custom arguments to do this as well eg.: > ./configure --with-blas="-L/home/user -lblas" > ./configure --with-blas="/opt/supafastblaswithstripesandachrometailpipe.a" ===== Automake default targets ===== The commonly used targets are: make # Compile everything. make clean # Remove all objects, temporary files and such. make distclean # Remove automatically generated autoconf/automake files. make dist # Create a tar.gz file containing source ready for distribution. make install # Install software to you kit. Other useful targets: make tags # Generate etags files for the source. make dist-zip # Create a zip file (great for windows people) make uninstall # Uninstall the files installed with make install make check # Run tests bundled with the project ===== The anatomy of a automake and autoconf governed project =====

Automake operates on a high abstraction level. You define the source files that are needed to build an executable or a library and automake generates the necessary make rules -- also rules for packaging and installing are automatically created. Automake reads Makefile.am and configure.in as input.

Autoconf is on the abstraction level of a normal Makefile. The main purpose of autoconf is create a configure script that finds necessary compilers and compiler flags. Autoconf also reads it's input from configure.in (or sometimes configure.ac). Automake depends on autoconf for generating the configure script. Autoconf can also be used stand-alone by creating a Makefile template in Makefile.in. When the configure script is run by the user, placeholders for compilers and compiler flags in Makefile.in are replaced with the platform specific values to create a Makefile.

autogen.sh # Semi-standard script for generating the configure 
           # script and possibly the Makefile.in files
           # by running automake and autoconf.
configure.[in,ac] # Definitions used for producing configure
Makefile.in # Autoconf makefile template
Makefile.am # Automake project description file.
===== Maintaining an autoconf project =====

If only autoconf is used, then Makefile.in is the file to edit. Autoconf variables appear as @VARIABLE@ like definitions (these are replaced with values found by the configure script). It is also possible to use autoconf definitions in Makefile.am files, this is especially useful for situations where automake functionality runs short. A snippet of Makefile.in can look like:

screensave.@OBJEXT@: screensave.c
@CC@ @CFLAGS@ -c -o $@ $<

Here, @OBJEXT@, @CC@, and @CFLAGS@ are replaced with values found by the configure script to create a normal makefile.

Maintaining an autoconf+automake project

If automake is used, the file to edit is Makefile.am. You can also mix custom Makefile directives in here, but stick with automake definitions whenever possible, as it will save a lot of time. A simple Makefile.am could look like this:

bin_PROGRAMS=hello
hello_SOURCES=hello.c hello.h someotherfile.f manylanguages.cpp

This example will create a configure that looks for working C, Fortran 77 and C++ compilers, ending up with a working Makefile that will compile the executable hello, which will be copmiled from a mix of C, fortran and C++.

===== Commands =====
autoscan    # Scan your source code to detect which tests might be needed and 
            # create a configure.scan, which can be used as a basis of 
	    # configure.in.
autoheader  # Scan configure.in and create a config.h.in file, that will 
            # be used as a basis of your config.h (if you use one)
automake    # Go through configure.in and Makefile.am files and create 
            # Makefile.in files.
autoconf    # Go through configure.in and create the configure script.

Still can't figure out what to run and in which order? Try running automake, aclocal, autoconf and autoheader in random combinations, and you'll usually end up with something useful after a couple of iterations. When you get a feeling of what is needed, write it down into autogen.sh, so you'll remember it next time.

===== Writing custom tests =====

You can write tests directly into configure.in. The language is a macro-language called M4, which is used to generate Bourne shell script. So you basically write in a mixture of sh and M4. Eg.

AC_MSG_CHECKING([for answer to meaning of life]) # M4 function call
answer="42" # sh variable assignment
AC_MSG_RESULT($answer) # M4 function call

Even writing modular and reusable M4+sh is possible, just take a look at the autoconf source for the default AC_* macros.

If you intend to write a lot of tests, it is beneficial to write them into separate .m4 files. This has an advantage of keeping configure.in more understandable. Eg. you might have a file acx_blas.m4 that contains a routine that gives a BLAS library as an argument to ./configure:

AC_DEFUN([ACX_BLAS], 
[
acx_blas_ok=no

AC_ARG_WITH(blas,
[AC_HELP_STRING([--with-blas=<lib>], [use BLAS library <lib>])])
case $with_blas in
yes | "") ;;
no) acx_blas_ok=disable ;;
-* | */* | *.a | *.so | *.so.* | *.o) BLAS_LIBS="$with_blas" ;;
*) BLAS_LIBS="-l$with_blas" ;;
esac

# Get fortran symbol name of sgemm (a blas routine).
AC_FC_FUNC(sgemm)

acx_blas_save_LIBS="$LIBS"
LIBS="$LIBS $FCLIBS $FLIBS"

# First, check BLAS_LIBS environment variable
if test "x$BLAS_LIBS" != x; then
save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"
AC_MSG_CHECKING([for $sgemm in $BLAS_LIBS])
AC_TRY_LINK_FUNC($sgemm, [acx_blas_ok=yes], [BLAS_LIBS=""])
AC_MSG_RESULT($acx_blas_ok)
LIBS="$save_LIBS"
fi
# restore the libs variable
LIBS=$acx_blas_save_LIBS
])

This can be then added to configure.in like this:

sinclude([acx_blas.m4])
ACX_BLAS
LIBS="$BLAS_LIBS $FLIBS"
===== CVS and autotools =====

CVS and autotools is an evil combination. AM_MAINTAINER_MODE is the key many of the problems with mixed up timestamps, but there are other things to know as well.

CVS updates often break autotools managed files files beyond repair. This can be seen as weird errors in while using make. One way to proceed might be to re-run configure to create everything -- or if even configure is broken a

rm configure ; cvs update configure ; ./configure 

will be a sure fix.

Alternatively, you can regenerate the configure yourself, if you have autotools installed:

sh autogen.sh ; ./configure 
===== Troubleshooting =====

When a test fails and configure fails to give a reasonable explanation of what went wrong (the usual case), searching config.log will often give more detailed information about what went wrong.

===== More information =====

The best way to learn is to study (i.e., steal) code from others -- just search for projects that use the same libraries and programming languages that you do. The documentation that comes with automake and autoconf is extremely good:

Autoconf manual

Automake manual

There is also a semi-official autoconf macro index contains a wide range of tests. They might not be perfect, but usually are a good starting point.

Autoconf macro archive

Another useful reference is the code itself. Need to know a shell variable that is produced by some test? Look it up from the autoconf/lib/autoconf directory of autoconf source.

Libtool is another useful tool to learn, for making cross-platform libraries, but libtool is not discussed here.

Autoproject is a tool that creates a skeleton automake and autoconf managed project.