1. Motivation
I'm a big fan of the GNU autotools suite, comprising autoconf, automake, libtool, and other tools. They are often considered as hard to use, but when all tools are used from the very beginning of a project, it's actually quite easy. I wrote this tutorial to show the basic steps required to setup an autotools based project. It does not require detailed knowledge of Makefiles or any of these tools to get started.2. Advantages
The autotools framework is especially beneficial for open source projects. For instance, AutoMake automatically creates Makefile rules to generate release tarballs, containing everything required for the user to rebuild the package. To sum up, here are some key advantages:- Makefile generation
- complete dependency tracking (from configure scripts, Makefile and its template files, and the actual source code files)
- extensive configure help
- easy to modify compile parameter
- convenience Makefile rules "make dist", "make distcheck" for releases
- support for out-of-source builds
- does not require any tool for the user of the software (only a shell and make)
3. Prerequisites
You need to install the following packages to make use of all autotools:- autoconf
- automake
4. Getting started
Here is a quick overview of the necessary steps to create a build environment based on the autotools.4.1. The main program
Consider having the following source code:#include <stdio.h> int main( int argc, char **argv ) { printf( "Hello World\n" ); return 0; }Put this text into a file named hello.c into a src subdirectory. It does not have to be a subdirectory, but it's good thing to put all source files into one directory to have a clean main directory.
4.2. Automake files
Now create the automake files. It is possible to just a single one for the whole project, but we will use a separate Makefile for the src directory.So first create the top-level file Makefile.am with just the content
SUBDIRS = srcNow in the src directory, create another file Makefile.am with the content
bin_PROGRAMS = hello hello_SOURCES = hello.cThis just says that there will be one program called "hello" (to be installed in the bin directory), and its sources are just the hello.c file.
4.3. Autoconf files
Now run autoscan to generate a configure template script. It will automatically consider the automake files. Rename the file to configure.ac.Edit the file and add
AM_INIT_AUTOMAKEat the end of the first block of lines. This basically says that automake should be initialized too. You should also change the name and version in the AC_INIT line.
GNU autotools require some files to exists, so execute
touch NEWS README AUTHORS ChangeLogto get those.
The final file will look like this:
# -*- Autoconf -*- # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS]) AC_CONFIG_SRCDIR([src/hello.c]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE # Checks for programs. AC_PROG_CC # Checks for libraries. # Checks for header files. # Checks for typedefs, structures, and compiler characteristics. # Checks for library functions. AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT
4.4. Generate final files
The project is set up so that the tool autoreconf can be used it initialize all necessary tools of the autotools suite. So just executeautoreconf -ito let it create all necessary files.
Basically it calls aclocal, automake, autoconf, autoheader in correct order to create all files, but since all tools play well together, autoreconf is just enough.
4.5. Build
Now you can run./configure && maketo build the program.
5. Extending the project
Once the the basic skeleton is working, adding more source files is easy, just add the Makefile.am and add any file to the *_SOURCES line, it can be c or header files, even from different types (like C or C++ files). Then just call make and the dependencies will take care of recreating the correct Makefiles.6. Creating a release
Automake automatically adds some Make targets to create release tarballs and even to check if it builds correctly out of that file.To create a release file, you just need to execute:
make distThis command will create a tarball named after the project name and version in the configure.ac file.
It's a good idea to let automake check if the release archive is complete and builds. For that, the make target distcheck has been added also. Instead of make dist, execute
make distcheckIt will also create a release archive, but additionally it will extract the archive into a temporary directory and try to run configure && make. The make output will indicate whether or not the build was successful.
7. Adding external libraries
At some point you often want to use additional libraries within your project. Adding those is very easy if they have a pkg-config entry (which most libraries nowadays bring). You can use the following macro in configure.ac to check for a given package and get all relevant compile parameters:PKG_CHECK_MODULES([SDL2],[sdl2])The first paramter is an arbitrary name within the configure system. The second name is the actual pkg name. Here we are using libsdl2 (or the sdl2 package to be more specific). In the Makefile.am you can reference the compiler flags and linker flags like this:
hello_CFLAGS = @SDL2_CFLAGS@ hello_LDADD = @SDL2_LIBS@The prefix SDL2_ is constructed by using the first argument of PKG_CHECK_MODULES, so whatever you put there needs to be used here. It is also possible to check for minimum or exact version, and to add addtional actions when the package is found or not found:
PKG_CHECK_MODULES([CHECK], [check >= 0.9.4], [usetests=yes], [usetests=no])