Let's add Automake to our program

Wow, you've gotten far. All you gotta do now is to add Automake to your program.

What is Automake?

Automake is a program that will automatically generate the “Makefile” for you. Although we already have a working “Makefile”, it's not quite portable. For example, should the Makefile use “cc” or “gcc”? Or should the name of the executable be “myprog” or “myprog.exe”? You see, portability doesn't only affect our source code, but our Makefile as well.

Automaking

Automaking involves three steps. But you should already be familiar with step #3:

  • Create a file named “Makefile.am”.
  • “Makefile.am” will be used by Automake to create a new “Makefile.in”.
  • “Makefile.in” will be used by “configure” to create “Makefile”.

You've already done #3 before. So we just need to create “Makefile.am” then generate “Makefile.in” from it.

Here's the “Makefile.am” we'll be using (no, you can't auto-generate it so you'll need to type it up yourself):

bin_PROGRAMS=hello
hello_SOURCES=hello.c

Simple, right?

bin_PROGRAMS tells what the name of our program(s) is, which is “hello” in our case. And hello_SOURCES tells what source files are used to create our program “hello”. In our case, we only have one source file, “hello.c”. (You may want to create programs with multiple sourcefiles in the future. In such a case, separate the arguments with spaces.)

There are many more commands you can use in the “Makefile.am”, such as commands to build libraries, go into subdirectories, etc. But for now, this is only what we need and this is what we'll use. If you're curious, please refer to the Automake manual or other documents for the details.

Now, we'll Automake this file. This requires two steps:

  • automake — Executing this command will certainly produce many errors. We'll need to check each error and fix it.
  • aclocal — While dealing with step #1, we'll be adding some Automake macros into “configure.ac”. This will freak out Autoconf because Autoconf won't understand these new macros. But we'll be able to calm Autoconf down by creating a file called “aclocal.m4” with the definitions of the newly added macros. “aclocal” will create this file for us automatically.

Dealing with errors

Now, let's run automake and see what errors we'll need to fix:

$ 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'
$

These errors will be different for you if you use a different version of Automake and/or Autoconf, so you may need to fudge through your errors yourself. But I'll show you how I deal with mine to give you an idea of how to deal with yours:

The first error is easy. I'll simply change AC_CONFIG_HEADER to AM_CONFIG_HEADER in “configure.ac”. Automake is just telling you here it prefers its version of the macro instead of Autoconf's version:

...
#AC_CONFIG_HEADER([config.h])
AM_CONFIG_HEADER([config.h])
...

As for the errors about PACKAGE and VERSION, this information can be added to "configure.ac" in several ways. The best way here is to add AM_INIT_AUTOMAKE(hello, 1.0) here, right after AC_INIT(…):

...
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AM_INIT_AUTOMAKE(hello, 1.0)
...

It may look like I just pulled a fast one on you by pulling this macro out of nowhere. But in fact, this is one of the few standard macros you should know when you use Automake. The first argument to the AM_INIT_AUTOMAKE is the name of the package, and the second argument is the version of the package. Memorize it!

Following errors are lots of messages about missing files. Some, you should create yourself (like “NEWS”, “README”, “AUTHORS”, and “ChangeLog”). As for the others, you can copy from elsewhere in your hard drive (Automake has a directory full of files you can copy.)

For example, I got “install-sh”, “mkinstalldirs”, and “missing” in “/usr/share/automake/”. These are some standard scripts used by Autoconf and Automake. I'll just copy these programs into my directory. Yours may be installed elsewhere so you may wanna look for them using “locate” or “find”.

As for “INSTALL”, the document describing how to install the program, I can probably the copy the version in “/usr/share/automake/”. But I should review it to make sure it's got good instructions for installation. And as for “COPYING”, the software license, I can copy the version in “/usr/share/automake/” if I'm writing a GPL program, or I'll need to roll my own.

$ 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 .
$ ls
AUTHORS    Makefile.am      autoscan.log  config.status*  hello.c
COPYING    Makefile.in      config.h      configure*      install-sh*
ChangeLog  NEWS             config.h.in   configure.ac    missing*
INSTALL    README           config.h.in~  configure.scan  mkinstalldirs*
Makefile   autom4te.cache/  config.log    hello*          stamp-h.in
$

The next error is generated because of a bug in Autoconf/Automake interoperability. If you open up “configure.ac”, you'll notice the line that looks like:

AM_CONFIG_HEADER([config.h])

It's actually a line you modified earlier from AC… to AM….

This line should actually look like:

AM_CONFIG_HEADER(config.h)

Anyway, make the adjustment.

The last two errors seem to imply Automake wants two lines of of code added to “configure.ac”. But actually, these line will be added by macros we already added to “configure.ac” above. So we'll ignore these two errors.

Now, let's re-Automake:

$ automake

That's what we want. If you get errors, fix them!

Let's Autoconf again

Since we modified “configure.ac”, we need to re-run “autoconf”. But even before we can do that, we need to run “aclocal”.

You see, Autoconf knows only about its own macros. These are the macros that start with AC…. Since we added Automake's macros to Autoconf (the AM… macros), we need to grab these macros from somewhere and put them somewhere Autoconf can find. Well, it turns out “aclocal” program knows where to grab these macros (from Automake's directory) and where to put them (into “aclocal.m4”.) So just run aclocal:

$ aclocal
$ ls
AUTHORS      Makefile.in      config.h        configure.ac    mkinstalldirs*
COPYING      NEWS             config.h.in     configure.scan  stamp-h.in
ChangeLog    README           config.h.in~    hello*
INSTALL      aclocal.m4       config.log      hello.c
Makefile     autom4te.cache/  config.status*  install-sh*
Makefile.am  autoscan.log     configure*      missing*
$

Nothing exciting there…

Now we can re-Autoconf, configure, then compile:

$ 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: config.h is unchanged
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 
1053956323.746657
$

Good! Remember, the exact output will depend on the version of Autoconf and Automake you use!

You should now also be able to pass arguments to “./configure”, run “make install”, etc. But I'll let you enjoy doing those things yourself. Summary

So, here is how we can use Automake:

  • Create “Makefile.am”.
  • Run “automake”.
  • Fix error messages.
  • Run “aclocal”.
  • Autoconf everything.
  • Configure, compile, and enjoy!

What's next?

Great job, Reader! That was it! Now you can program using Autoconf and Automake! Of course, there are many more macros and tricks and tips you'll want to learn, but now you should be able to learn those pretty easily, one at a time, as needs arise.

Now, let's do a global summary of what we've learned, and let me also give you some last pointers.

Next: Chapter 5 — Autotools tutorial summary

results matching ""

    No results matching ""