For small UNIX development C/C++ projects, manually created Makefiles for make are usually well for building the source code. However, when source code base grows larger, there is a need to automate the building process.
Like, you may have a need to automate following things:
- Compile-time options without modifying Makefile.
- Library and header files dependency tracking.
- Code portability for different platforms.
- Integration to binary package building (rpm/deb in Linux or ports in BSD).
- Binary installation targets (/usr/bin, /usr/local/bin) for varying platforms.
- Source code tarball generation.
we can do all of these with Makefiles, but it will be quite painful to maintain especially in larger projects. Fortunately, there is a way around to manage it all. Autotools can be used to automate building, installation and maintenance of source code. They are range of tools, with two main components called autoconf and automake and others are like autoscan, autoheader, autoreconf, autoupdate and libtool..
We will go with a example project with autoconf. Use this as a skeleton of a new development project.
Running the autogen.sh script and configure is usually necessary only for the first time when bootstrapping a local copy of the source code. After that you can just type “make”. The generated configure script is usually automatically invoked when you do modifications to configure.ac or Makefile.am. However, it is sometimes necessary to run autogen.sh when you do extensive changes to configure.ac.
How to Migrate an Existing Project to Autotools
Make sure that you have autoconf (1.9 or later), automake and libtool installed on your machine before trying the example project described in here. Change your working directory to the project directory.
Here, you will see how I have wrapped the project around autotools from scratch. I started by creating Makefile.am file manually:
Makefile.am
AUTOMAKE_OPTIONS = foreign
AUTOMAKE_OPTIONS = subdir-objects
ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS}
bindir = /usr/CL_CM
bin_PROGRAMS = ZS
ZS_SOURCES = src/ZS.cpp src/WS.cpp src/US.cpp src/msdb.cpp src/MU.cpp src/RSA.cpp src/WS.h src/US.h src/msdb.h src/MU.h src/RSA.h src/SE.h src/RL.h
ZS_CPPFLAGS = -Wall -ansi -I /usr/include/mysql
ZS_LDADD = -lmysqlclient
dist_noinst_SCRIPTS = autogen.sh
then enter a following command, It creates a configure.scan file.
$ autoscan
now rename this configure.scan as configure.ac.
$ mv configure.scan configure.ac
then edit configure.ac so that it contains following lines with your project details.
configure.ac (order is significant)
AC_PREREQ([2.65])
AC_INIT([ZS], [1.0], [bugs@cl.com])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE(ZS, main)
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_MAKE_SET
# Checks for libraries. you can add required libraries here
AC_CHECK_LIB([mysqlclient], [mysql_init], [],[
echo “mysql library is required for this program”
exit -1])
# Checks for header files.
AC_CHECK_HEADERS([arpa/inet.h fcntl.h netinet/in.h stdlib.h string.h sys/ioctl.h
sys/socket.h sys/time.h unistd.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_HEADER_STDBOOL
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_REALLOC
AC_CHECK_FUNCS([floor memset select socket])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
Now create autogen.sh file with exact like following content.
#!/bin/sh -e
test -n “$srcdir” || srcdir=`dirname “$0″`
test -n “$srcdir” || srcdir=.
autoreconf –force –install –verbose “$srcdir”
test -n “$NOCONFIGURE” || “$srcdir/configure” “$@”
after that run this autogen.sh which creates the configure script
$ ./autogen.sh
Now run this generated configure script with next command. It checks dependencies & can be given compile options (–enable-xx)
$ ./configure
Project now configured and makefile is generated accordingly, Now you build the project make.
$ make
Some other automatically generated targets for make are:
Clean all temporary files
$ make clean
Installs binaries, libraries & docs(requires root privileges).
$ make install
create a distribution tarball
$ make dist
“make dist“. creates a tarball of the source code that developer distributes to users. It does not include the autogen.sh script at all. Instead, it includes a prebuilt configure script and the source files. Users can build the source code from the tarball as follows:
$ ./configure
$ make
Thanks.
