Using Autotools
In the first chapter, we have not really used the Autotools. It is not need to compile a project from the sources. But all files in the build process are not written by hand but generated from templates using Autotools.
Autotools is composed of several tools: aclocal, autoconf, automake and other that we will not see here, belonging to two packages: Automake and Autoconf.
- Autoconf is used to generate the configure script, from a template named configure.ac. The configure script will check all characteristics of the host system and generate the makefiles from Makefile.in templates.
- Automake is used to generate complete Makefile.in templates, following GNU standards from very simple Makefile.am templates.
Now let's see a minimal example to start grasping the relationships between the various files.
- 3.1.1. Write sources
- 3.1.2. Run Autoconf
- 3.1.3. Run Automake
- 3.1.4. Build project
- 3.1.5. Clean project
- 3.1.6. Generate project
3.1.1. Write sources
- Create an empty directory called tut_prog and enter in it.
- In this new directory, create a new file named main.c containing:
#include <stdio.h> int main() { printf("Hello world!\n"); return 0; }
3.1.2. Run Autoconf
- Write the following in a file named configure.ac:
AC_INIT([Tutorial Program], 1.0) AM_INIT_AUTOMAKE AC_PROG_CC AC_CONFIG_FILES(Makefile) AC_OUTPUT
The configure template script could be named configure.in. It is the name used in older version (before 2001) of Autoconf. Nevertheless, it is recommended to use configure.ac because the .in extension is already used by files processed by configure and generated by Automake: Makefile.in and autoheader: config.h.in.
AC_INIT, AM_INIT_AUTOMAKE, etc... are M4 macros. M4 is a macro expanding software used by Autotools; we don't need to know about it. When Autoconf will process this configure.in, the macros will be expanded and we will get a fresh huge configure script.
- AC_INIT
-
Is the first mandatory macro. We need to indicate the name of the project and its version.
- AM_INIT_AUTOMAKE
-
Initialize environment for Automake. It is needed in all projects using Automake.
- AC_PROG_CC
-
Determine the C compiler to use.
- AC_CONFIG_FILES
-
Create each file by copying the corresponding template file (with .in extension) and substituting the output variable values.
- AC_OUTPUT
-
Marks the end of the configure template.
The use of some macros has changed between different versions of Autoconf:
- The package name and version was defined as arguments of AM_INIT_AUTOMAKE instead of AC_INIT.
- AC_OUTPUT was getting the list of generated files instead of using the additional macro AC_CONFIG_FILES.
Autoconf only knows its own macros but read additional ones in a file named aclocal.m4. These macros are used to extend Autoconf, it includes Automake macro (starting with AM_) and other third party macros. For instance, if you develop a library called foo, you might want to write an AC_CHECK_FOR_FOO macro so that developers using your library can check for its presence using Autoconf.
aclocal scans configure.ac and create an aclocal.m4 file which contains the macros mentioned in configure.ac. aclocal is part of the Automake package and search by default in Automake macros and in a system path typically /usr/share/aclocal.
- Launch aclocal. It will create a new file named aclocal.m4 in the current directory.
- Launch autoconf. It will create the configure script configure.
On my system, I actually get an extra directory called autom4te.cache. That is for Autoconf internal purposes. You do not need to care about it.
3.1.3. Run Automake
- Write the following in a file named Makefile.am:
bin_PROGRAMS = tut_prog tut_prog_SOURCES = main.c
In Makefile.am are the very essential data needed to build the project: the target program, called tut_prog, will be put in a $prefix/bin/ directory; to build it we need main.c. Note that we don't specify how that will be built: Automake will figure it out. We haven't even mentioned the compiler in this pre-makefile.
Makefile.am will be processed by Automake; the result will be a Makefile.in. This Makefile.in is close to being a real makefile, but it contains variable names which will be replaced when the configure script will run, resulting in a real makefile (called Makefile). For instance, configure will write in the final Makefile what compiler to use (it is the compiler it found using the AC_PROG_CC macro).
- Run the command automake --add-missing --foreign. It will create a new file named Makefile.in as expected. Moreover, due to the switch --add-missing you get a few links to scripts necessary for building the project: depcomp, install.sh and missing. The other option --foreign tells to Automake that you don't want to follow GNU standard and you don't need mandatory documentation files: INSTALL, NEWS, README, AUTHORS, ChangeLog and COPYING. I have used it here to keep the number of created file to a minimum but else it is a good idea to provide these files, you can start with empty files.
3.1.4. Build project
-
Run now the new configure script: ./configure. You get the following output and it create the makefile for your program.
checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for a thread-safe mkdir -p... /bin/mkdir -p checking for gawk... gawk checking whether make sets $(MAKE)... yes checking for gcc... gcc checking for C compiler default output file name... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for suffix of executables... checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ISO C89... none needed checking for style of include used by make... GNU checking dependency style of gcc... gcc3 configure: creating ./config.status config.status: creating Makefile config.status: executing depfiles commands
-
Run now make, to build your program. You get the following output and a new tut_prog executable
gcc -DPACKAGE_NAME=\"Tutorial\ Program\" -DPACKAGE_TARNAME=\"tutorial-program\" \ -DPACKAGE_VERSION=\"1.0\" -DPACKAGE_STRING=\"Tutorial\ Program\ 1.0\" \ -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"tutorial-program\" -DVERSION=\"1.0\" \ -I. -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.c main.c: In function ‘main’: main.c:5: warning: return type of ‘main’ is not ‘int’ mv -f .deps/main.Tpo .deps/main.Po gcc -g -O2 -o tut_prog main.o
-
Now, if you can write in /usr/local/bin, run make install to install your program. Else you need to log as root before or use sudo and run sudo make install. You should get.
make[1]: Entering directory `/home/seb/Projects/Tutorial' test -z "/usr/local/bin" || /bin/mkdir -p "/usr/local/bin" /usr/bin/install -c 'tut_prog' '/usr/local/bin/tut_prog' make[1]: Nothing to be done for `install-data-am'. make[1]: Leaving directory `/home/seb/Projects/Tutorial'
Then, if /user/local/bin is in your path, you can run your program from everywhere.
3.1.5. Clean project
-
The program is installed, so you can clean the build directory running make clean. It removes all object files and the program but not the makefiles.
test -z "tut_prog" || rm -f tut_prog rm -f *.o
You can still run the program installed in /user/local/bin.
-
To remove the installed program, run make uninstall. Like for the installation, you need to use have the writing right in the directory or use su or sudo.
rm -f '/usr/local/bin/tut_prog'
3.1.6. Generate project
Running aclocal, automake and autoconf one by one is fine for a tutorial to understand exactly what's happen. But, for a real work, it's a bit tedious especially because there are other tools those could be needed like autoheader, autopoint or libtoolize. After creating the project, the makefiles generated by configure should take care of regenerating configure and all Makefile.in. Anyway, this lets a room for improvement and there are even two responses to this:
- autoreconf
-
It is another tool part of the Autoconf package which is running all scripts in the right order. To start a new project, you can just run autoreconf --install and it will call all necessary commands.
- autogen.sh
-
It is a script not part of Autotools, that it doing the same thing. There is one named gnome-autogen.sh which comes with GNOME common development package but other project can write their own ones.