Getting Started with Automake and Autoconf

July 15, 2004

This little example will show you how to setup a project using the auto tools and also show you how to compile in a static library with your project. Creating shared libraries are for a different story. I'm assuming you're familiar with downloading an open source project and running ./configure and make. This basically shows how to automate setting up those commands.

First of all, we need to agree upon a source tree structure for this example. I usually do something like the following...

router/:
ChangeLog COPYING doc/ Makefile.am src/ autogen.sh* configure.in README

router/src:
dvrouter.h main.cpp dvrouter.cpp libjdhsocket/ Makefile.am

router/src/libjdhsocket:
clientsocket.cpp serversocket.cpp socketbase.cpp clientsocket.h
Makefile.am serversocket.h socketbase.h

Of course, you can use really any damn structure you like, but just bear with me here.

First thing to do is create a configure.in file (in new versions it's configure.ac) file. This file basically tells autoconf where stuff is and what to do. Here is a very basic configure.in file.
AC_INIT(router,1.0)
 
AM_INIT_AUTOMAKE
 
AM_CONFIG_HEADER([src/config.h])
 
CFLAGS=" $CFLAGS -g"
 
CXXFLAGS=" $CXXFLAGS -g -DDEBUG"
 
LDFLAGS=" $LDFLAGS -g"
 
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_AWK
AC_PROG_RANLIB
 
# Checks for header files.
AC_HEADER_STDC
 
AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h malloc.h netdb.h \
netinet/in.h stddef.h stdlib.h string.h sys/ioctl.h sys/socket.h sys/time.h unistd.h])
 
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_CHECK_TYPES([ptrdiff_t])
 
# Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_FUNC_MEMCMP
AC_CHECK_FUNCS([gethostbyname gettimeofday memmove memset pow select socket])
 
AC_PATH_PROG(routerpath, router)
AC_OUTPUT([Makefile src/Makefile src/libjdhsocket/Makefile])
 
echo
echo $PACKAGE $VERSION
echo
eval eval echo router will be installed in $bindir.
if test "x$routerpath" != "x" ; then
	echo Warning: You have an old copy of router at $routerpath.
fi
echo
echo configure complete, now type 'make' and then 'make install'
echo
Add the following Makefile.am to the root directory. this is the same directory your configure.in is located.
SUBDIRS = src
This Makefile.am is for the src directory. This basically defines the program and tells it to look into the subdir and compile the lib we are going to statically link in. Notice the cool syntax and other fun things.
bin_PROGRAMS = router
 
router_SOURCES = main.cpp dvrouter.cpp dvrouter.h
 
SUBDIRS = libjdhsocket
 
router_LDADD = libjdhsocket/libjdhsocket.a
The last Makefile.am, the one for the socket library, is pretty simple and of course it goes in src/libjdhsocket/
noinst_LIBRARIES = libjdhsocket.a
 
libjdhsocket_a_SOURCES= 	clientsocket.cpp 
				clientsocket.h 
				serversocket.cpp 
				serversocket.h 
				socketbase.cpp 
				socketbase.h

Now we've got everything setup. However, automake and autoconf need a bunch of other shit to actually work. There are several command used to "initialize" your source tree so automake knows everything about it and what to do. So, I usually execute a file like this to initialize. Call it autogen.sh or something similar. This isn't really something that's distributed. It's just used for you while developing. If you change the configure.in file or doing anything drastic, it's probably a good idea to run this again.

#! /bin/sh
 
autoheader -f
touch NEWS README AUTHORS ChangeLog
touch stamp-h
aclocal
autoconf -f
automake --add-missing -c

That's it! Now you've got it setup and you can ./configure and make to setup and compile the project.

Now, I havn't gone into any depth or really explained all of the details, but that's where you come in. The auto tools are definately the way to go, especially for public open source projects that are going to be compiled on who knows what kind of machine.

Related Posts

1 Comment

Comment September 8, 2006 by anonymous
Thank you for help. I found your post through google and it works.