I wrote a charming little utility for linux called
getkey, that captures the keystrokes and displays them on the screen using OSD. Its called gekey and has a couple of .c files and a hand crafted Makefile to go along with it.
But I wanted to use the auto-tools (autoconf and automake) to create a configure script and a Makefile so that my utility could by installed like any other GNU tool using the famous:
./configure && make && make install
When I went hunting for autotools tutorials, they were too elementary (based on a hello.c, with no dependency check) or too long, 100 page books on autotools.
My program has a couple of dependencies (xosd, Xtst, X11) and it is small enough to understand. So I decided to use this program to write a quick and dirty tutorial for autotools, with dependency checks.
These are the steps I followed to achieve that and here are the files that I'll be using for this example.
getkey_example.tar.gz
Required Tools:
Make sure the following tools are available on the system, before getting started.
tar
make
aclocal
autoconf
automake
This tutorial is based on autoconf ver 2.63.
Setup:
In order to generate the configure script and the Makefiles, we need to define a set of rules and dependencies. This is done via two files '
configure.ac' and '
Makefile.am'.
Generating the configure script:
1. Leave the default Makefile in the project folder and run '
autoscan'. It will create a vanilla
configure.scan file.
2. Now move the Makefile to a different place (so it doesn't interfere with the autogenerated files in future).
mv Makefile ../.
3. Rename
configure.scan to
configure.ac (this used to be configure.in for old versions, it is deprecated now).
4. Edit
configure.ac and modify these lines.
WAS:
AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
IS:
AC_INIT([getkey], [0.1], [email-address])
WAS:
# FIXME: Replace `main' with a function in `-lX11':
AC_CHECK_LIB([X11], [main])
# FIXME: Replace `main' with a function in `-lXtst':
AC_CHECK_LIB([Xtst], [main])
# FIXME: Replace `main' with a function in `-lxosd':
AC_CHECK_LIB([xosd], [main]) Chose one function from each of the libraries used in the program and replace '
main' with the function name. Any one function is enough to verify a library.
IS:
AC_CHECK_LIB([X11], [XOpenDisplay], [],[
echo "X11 library is required for this program"
exit -1])
AC_CHECK_LIB([Xtst], [XRecordCreateContext], [],[
echo "Xtst devel library is missing. Xtst is required for this program"
exit -1])
AC_CHECK_LIB([xosd], [xosd_create], [],[
echo "xosd devel library is missing. xosd is required for this program"
exit -1])
SYNTAX:
AC_CHECK_LIB([libname],[func-name],[action-if-found],[action-if-not-found]) The line breaks are essential in the fourth parameter to the function AC_CHECK_LIB(). This is to make sure that configure script will exit when it can't find a dependency.
5. In configure.ac check for the line that has AC_CONFIG_FILES(). This tells the autoconf tool what are the output files. It should typically be
AC_CONFIG_FILES([Makefile])
6. Run autoconf.
autoconf
This will create the first version of configure script.
Generating the Makefile:
1. Add this line to the
configure.ac
AM_INIT_AUTOMAKE([getkey], [0.1]) This instructs automake to generate makefiles after the configure script is run.
This will also define two constants PACKAGE(=getkey) and VERSION(=0.1) during make. This can be used in the code to display version specific print outs.
If you don't have a config.h file for configuration, then comment out the line: (I didn't use this in getkey)
AC_CONFIG_HEADERS([config.h])
2. Create a file named Makefile.am and add these lines.
AUTOMAKE_OPTIONS = foreign
CFLAGS=-Wall -I/usr/local/include -DVERSION=\"$(VERSION)\" -DPROG="\"$(PACKAGE)\""
LDFLAGS=-L/usr/local/lib -lX11 -lXtst -lxosd
bin_PROGRAMS = getkey
getkey_SOURCES = getkey.c circ_list.c
The first line
AUTOMAKE_OPTIONS = foreign is to let automake know that it is not a standard GNU package.
A standard GNU package requires certain folders and files to be present, such as doc, src, INSTALL, COPYING, etc.
The CFLAGS and LDFLAGS is copied from the current Makefile that we moved to a different location.
bin_PROGRAMS = getkey is the name of the resulting executable.
getkey_SOURCES = getkey.c circ_list.c, this is the list of sources that will compile to result in getkey. List all the source files here.
If you have more than one resulting executable you can do
bin_PROGRAMS = prog1 prog2 prog3
LDFLAGS=-L/usr/local/lib -lX11 -lXtst -lxosd
bin_PROGRAMS = getkey
getkey_SOURCES = getkey.c circ_list.c 3. For our grand finale we run these commands
aclocal
autoconf
automake -a
aclocal is a tools that generates aclocal.m4 based on the configure.ac file which is used as an input to the autoconf tool.
autoconf will generate the configure script and
automake takes Makefile.am as input and creates Makefile.in.
Now we have the final version of our configure script.
Ready to go:
1. Test out the configure script and the Makefile.
./configure
make
2. Create a package. Now that everything is working as expected, we can create a package for distribution.
make dist
This will create a tar.gz file with the package name and version number. Now it is ready for release to the world. Here you go
getkey-0.1.tar.gz.
References:
http://sourceware.org/autobook/autobook/autobook_toc.html#SEC_Contents
http://www.amath.washington.edu/~lf/tutorials/autoconf/toolsmanual_toc.html
http://www.developingprogrammers.com/index.php/2006/01/05/autotools-tutorial/