Autotools tutorial summary
Review
So let's put everything together. This is how we use Autoconf and Automake:
- Create your sources. (Be sure to have a simple “Makefile” to help Autoconf autodetect things better.)
- Run “autoscan” to generate “configure.scan”.
- Rename “configure.scan” to “configure.ac”.
- Run “autoheader” to generate “config.h.in”.
- Make your source portable by looking at “config.h.in”. (We previously did this at a later step by reading “config.h”, but we can do it in this step by referring to “config.h.in” instead.)
- Create “Makefile.am”.
- Run “automake”.
- Fix errors and run “automake” again.
- Run “aclocal”.
- Run “autoconf”.
- Configure, make, and run!
This seems pretty crazy. And it gets crazier: Subsequent runs of “autoheader”, “autoscan”, “autoconf”, “automake”, and “aclocal” will modify more files, which means you'll need to run more of “autoheader”, “autoscan”, “autoconf”, “automake”, and “aclocal” again to sync all files, which will cause more files to change…. Often times you won't even know which files need syncing so you'll just run any of these commands at random to get the files to sync. Don't worry — it's normal.
Let's try again from scratch
Why don't we try compiling our program again, but this time from scratch? This time, we'll start out with only Makefile, Makefile.am, and hello.c:
$ ls
Makefile Makefile.am hello.c
$ autoscan
$ mv configure.scan configure.ac
$ autoheader
autoheader2.50: `config.h.in' is created
$ automake
configure.ac: 4: `automake requires `AM_CONFIG_HEADER', not `AC_CONFIG_HEADER'
automake: configure.ac: `PACKAGE' not defined in `configure.ac'
automake: configure.ac: `VERSION' not defined in `configure.ac'
automake: configure.ac: required file `./install-sh' not found
automake: configure.ac: required file `./mkinstalldirs' not found
automake: configure.ac: required file `./missing' not found
automake: Makefile.am: required file `./INSTALL' not found
automake: Makefile.am: required file `./NEWS' not found
automake: Makefile.am: required file `./README' not found
automake: Makefile.am: required file `./COPYING' not found
automake: Makefile.am: required file `./AUTHORS' not found
automake: Makefile.am: required file `./ChangeLog' not found
configure.ac: 4: required file `./[config.h].in' not found
automake: configure.ac: AC_ARG_PROGRAM must be used in `configure.ac'
automake: configure.ac: AC_PROG_INSTALL must be used in `configure.ac'
$ vi configure.ac
$ cp -a /usr/share/automake/install-sh .
$ cp -a /usr/share/automake/mkinstalldirs .
$ cp -a /usr/share/automake/missing .
$ touch NEWS README AUTHORS ChangeLog
$ cp -a /usr/share/automake/INSTALL .
$ cp -a /usr/share/automake/COPYING .
$ automake
$ aclocal
$ autoconf
$ ./configure
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking whether make sets ${MAKE}... yes
checking for working aclocal... found
checking for working autoconf... found
checking for working automake... found
checking for working autoheader... found
checking for working makeinfo... found
checking for gcc... gcc
checking for C compiler default output... 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 how to run the C preprocessor... gcc -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking whether time.h and sys/time.h may both be included... yes
checking for gettimeofday... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
config.status: executing default-1 commands
$ make
gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -c hello.c
gcc -g -O2 -o hello hello.o
cd . && autoheader
autoheader2.50: `config.h.in' is updated
cd . \
&& CONFIG_FILES= CONFIG_HEADERS=config.h \
/bin/sh ./config.status
config.status: creating config.h
config.status: executing default-1 commands
$ ./hello
1053959038.671747
$
Awesome!
Miscellaneous information
I left out some information in our tutorial that you may find useful.
Just because you go through all these steps doesn't mean you program will be 100% portable. As you continue to expand your program, you'll find it won't compile properly on some platforms. Then hopefully someone will send you a bug report about it, and you'll be able to fix it by customizing “configure.ac” for your program. This is normal and expect such situation to happen.
The main idea here is that your program won't be completely portable to start out, but you should expect it'll evolve to become more and more portable as time goes by, and you should also expect to modify “configure.ac” with your custom macros and tests.
Of course, that means you'll need to learn how to write custom macros, run tests, etc. These are advanced (actually, more like intermediate) topics you'll have to learn elsewhere. It's actually not that hard — just go through the info pages or the Internet one at a time as you need them. There's nothing to worry.
Once your program is ready for distribution, there is no need to distribute the intermediate files with your program. Files such as “configure.scan”, “autoscan.log”, “configure.ac”, etc. won't be necessary to distribute with your program. However, many people keep them around anyway, even though these files are useless unless the downloader also has the same versions of Autotools installed on their system as you. What you do is up to you.
All these Autoconf macros use a program called M4 to expand the macros into shell scripts. So these macros are called M4 macros. Many files we dealt with, including “configure.ac” and “aclocal.m4”, are M4 macros. These macros are expanded to create “configure”, which is a shell script.
Anyway, since there is so much of M4 macroing happening, it'll help you to know at least little about M4 macros. For more information on M4 macros, I recommend reading the info pages. I'm sure there are some good tutorials on the Internet, also.
There are several other programs you should know about when using Autoconf and Automake, such as “ifnames” and “autoreconf”.
“ifnames” is a program that identifies constants you use in your C program. It's useful if you want to know what constants you used in your program to make it portable. For example, if you run this program now on “hello.c”, it'll tell you you used two constants, HAVE_GETTIMEOFDAY and HAVE_SYS_TIME_H.
“autoreconf” is a program that runs Autoconf programs for you automatically, so you don't have to remember which Autoconf programs to run and in which order. But it won't work properly until you go through everything once first, so it comes in handy only after you go through the compilation process once through.
In addition, there are several other files that play important roles in Autoconf/Automake, especially “acinclude.m4” and “autogen.sh”. These aren't programs that are provided by Autotools, but rather files you create yourself.
If you ever create your own M4 macros, or if you ever want to use someone else's macros, you should put those new macros in a file called “acinclude.m4”. Then this file will be read by “aclocal” to generate a new “aclocal.m4” file, so Autoconf can use the new Macros in generating the “configure” script. If that confuses you, just remember to put any macros external to Autoconf and Automake in “acinclude.m4”.
As for “autogen.sh”, it's a shell script people often create to automatically reconfigure everthing. It's similar to “autoreconf”, but it's a custom version that also works with Automake and do other nifty things you may wanna do. The name of this file is just a convention, not a rule, but it's a good idea to follow the convention anyway, don't you think?