Introduction
Software is generally developed to be used on multiple platforms. Since each of these platforms have different compilers, different include files, there is a need to write Makefiles and build scripts so that they can work on a variety of platforms. The free software community (Project GNU), faced with this problem, devised a set of tools to generate Makefiles and build scripts that work on a variety of platforms. If you have downloaded and built any GNU software from source, you are familiar with theconfigure
script. The
configure
script runs a series of tests to determine information about your machine. The following is a sample output from
configure
.
foo@pastwatch: ...neel/projects/gpstat> ./configureProject GNU provides two programs,
loading cache ./config.cache
checking whether to enable debugging... yes
checking host system type... sparc-sun-solaris2.8
checking target system type... sparc-sun-solaris2.8
checking build system type... sparc-sun-solaris2.8
===========================================================
Setting up build environment for sparc solaris2.8
===========================================================
checking whether build environment is sane... yes
automake
and
autoconf
, that simplify the generation of portable Makefiles and configure scripts.
automake
is a program that generates makefile templates automatically from
Makefile.am
.
Makefile.am
and
automake
are described in detail below.
autoconf
is a tool that creates the configure file from
configure.in
.
autoconf
also provides a set of utility scripts that include
autoconf
,
aclocal
, and
autoscan
that help to generate the configure script.
GNU Build Tools -- Step by Step
The process flow when using GNU build tools is as follows.- Write
makefile.am
templates. - Write
configure.in
.
- 2.1 Use autoscan to generate a template.
- 2.2 Specialize the generated
configure.scan
to suit your project. - 2.3 Rename
configure.scan
toconfigure.in
.
- Run
automake
to generateMakefile.in
fromMakefile.am
(automake
scansconfigure.in
to find out more about the project). - Run
aclocal
to make local copies of allautoconf
macros. These macros are then included in the project. - Run
autoconf
to generateconfigure
.
automake
automake
, when used in conjunction with
autoconf
, makes creating
Makefiles
easy.
automake
operates on a
Makefile.am
to generate
Makefile.in
.
Makefile.in
is then processed by the
configure
script to generate
Makefile
.
Makefile.am
has macros that are processed by
automake
. A sample
Makefile.am
is shown below. Variables surrounded by
@
's are automatically propagated without change to
Makefile.in
. The
configure
script, when parsing
Makefile.in
into
Makefile
, makes the necessary substitutions (for example,
@LDFLAGS@
may get expanded to "
-lm -lthread
).
bin_PROGRAMS = gpstat
gpstat_SOURCES = about.c interface.c multi-plot.c attach_process.c
gpstat_LDFLAGS = @LDFLAGS@ @GTK_LIBS@ -lgthread
INCLUDES = @GTK_CFLAGS@
automake
knows the rules to create object files and executables for the platform it is running on. The above sets of macros tell
automake
that:
- The final executable is to be named
gpstat
. - The sources for
gpstat
are the value ofgpstat_SOURCES
. - Add
@LDFLAGS@
,@GTK_LIBS@
, and-lgthread
to the link line. (Theconfigure
script will replaceLD_FLAGS
andGTK_LIBS
with their proper values.) - Include the variable
$INCLUDES
in the compilation line.
autoconf
The configure
script is generated from configure.in
using autoconf
. configure.in
is a normal text file that contains several autoconf
macros. These macros specify what tests to carry out. General uses of the configure
script include:
- Find machine information (Hostname, version...).
- Find the path to a particular program (
bison
,lex
, ...). - Find out if a tool supports a feature (for example, if the compiler supports
bool
). - Check if the required libraries are available on your system.
- Process
Makefile.in
to generateMakefile
.
dnl
or a
#
. The following is a small, well-documented, self-explanatory
configure.in
file.
#============================start configure.in============================
dnl Process this file with autoconf to produce a configure script.
dnl notice how comments are preceded by "dnl"
# comments can also begin with a #
dnl This macro is a must, and this tests if the configure
dnl script is running in the correct directory
AC_INIT(src/about.c)
dnl This macro tells the configure script to put
dnl "defines" in a file rather than the command line.
AM_CONFIG_HEADER(config.h)
dnl get the flags
CFLAGS="${CFLAGS=}"
dnl this macro is used to get the arguments supplied
dnl to the configure script (./configure --enable-debug)
dnl Check if we have enable debug support.
AC_MSG_CHECKING(whether to enable debugging)
debug_default="yes"
AC_ARG_ENABLE(debug, [ --enable-debug=[no/yes] turn on debugging
[default=$debug_default]],, enable_debug=$debug_default)
dnl Yes, shell scripts can be used
if test "x$enable_debug" = "xyes"; then
CFLAGS="$CFLAGS -g -DDEBUG"
AC_MSG_RESULT(yes)
else
CFLAGS="$CFLAGS -O3 -ffast-math -mcpu=v8 -mtune=ultrasparc"
AC_MSG_RESULT(no)
fi
dnl tells us that we require autoconf with version greater than
dnl 2.12 to generate configure
AC_PREREQ(2.12)
dnl get system information
AC_CANONICAL_SYSTEM
dnl Since foo is currently untested on any os other
dnl than solaris, so check the os and quit if not solaris.
UNSUPPORTED_OS="FOO is currently unsupported on your platform.
If you are interested in making it work on your platform, you are
more than *welcome*. Contact foo@bar.sun.com for details."
case "${target_os}" in
solaris*)
echo ===========================================================
echo Setting up build environment for ${target_cpu}${target_os}
echo ===========================================================
;;
*)
AC_MSG_ERROR($UNSUPPORTED_OS)
esac
# Build time sanity check...
AM_SANITY_CHECK
dnl get path to install program
AC_PROG_INSTALL
AC_ARG_PROGRAM
VERSION=0.1
PACKAGE=foo
dnl initialize automake
AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
dnl Checks for c compiler.
AC_PROG_CC
dnl check for standard c headers
AC_HEADER_STDC
dnl export these variable (so Makefile substitutions
dnl can be made.
AC_SUBST(CFLAGS)
AC_SUBST(LDFLAGS)
dnl Checks for libraries.
dnl AC_CHECK_LIB(gthread, g_thread_init)
dnl AC_CHECK_LIB(pthread, pthread_create)
dnl Check for /proc
AC_CHECK_FILE(/proc,,AC_MSG_ERROR(Cannot
find /proc. See the file 'README' for help.))
dnl check for procfs.h
AC_CHECK_HEADER(procfs.h,,
AC_MSG_ERROR(Cannot
find procfs.h. See the file 'README' for help.))
dnl Checks for header files.
AC_CHECK_HEADERS(fcntl.h)
AC_CHECK_HEADERS(time.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_PID_T
dnl Create these files, making substitutions if necessary
AC_OUTPUT([
src/Makefile
Makefile
]
)
#============================end configure.in============================
automake
also provides autoscan
, a utility script that will help you create a template configure.in
. autoscan
scans the program sources and adds suitable macros to configure.in
. It creates configure.scan
, which then should be renamed configure.in
, after making suitable modifications.
automake
also provides a program called aclocal
. aclocal
makes local copies of all autoconf
macros, so that other developers can modify the configure.in
file.
You can combine the invocation of automake
, aclocal
, and autoconf
as follows:
foo@pastwatch$ aclocal&& automake && autoconf
Conclusion
automake
and
autoconf
are powerful tools that enable easier building of projects on various platforms. The only things you need to write are the
Makefile.am
and
configure.in
files. The use of these tools makes projects portable across several platforms. They are extremely configurable, and several predefined macros are already available for use. If you plan to make your projects available on a variety of platforms, you should consider using
automake
and
autoconf
.