Illustration of autoconf

From: Simon Sirca (sirca@crex.mit.edu)
Date: Sat Oct 06 2001 - 12:40:52 EDT


Hi, everybody,

I have prepared a "demo version" of the autoconf generation of Makefiles.
in case you want to get a flavour of how this thing works. It is a bit
awkward at first sight, but once it is tuned well on a growing amount
of code, it pays off with ease of maintenance and smaller likelihood
of compilation mistakes. For illustration purposes, it is only set up
with the BlastLib portion of the BLAST software distribution at the moment.
It does not interfere with the previous way used to compile it.

One of the main features is the separation of the source code, compilation
and installation directories. This is achieved by writing a set of
"Makefile.in" files in each pertinent source directory. There is a
configuration script called "configure" sitting at the top of the source
tree and which is invoked from an arbitrary compilation directory chosen
by the user. This script turns the Makefile.in files into Makefiles
and puts them into the appropriate subdirectories -- in this demo
version, configure will make one "top" Makefile and BlastLib/Makefile.
Saying "make" and "make install" at the top of the compilation
will then do all the compilation and installation. Note that
"configure" itself is generated from "configure.in" by autoconf.
All platform-dependent issues should be addressed only in the
configure.in script, so that features propagate correctly into
the Makefiles. Bottomline: do not touch anything which does NOT
have an .in extension.

Beginner's demo
---------------

In the CVS repository, you will notice a couple of new files:

blast/__BLAST__
blast/Makefile.in
blast/Makefile.inc.in
blast/config.sub
blast/config.guess
blast/configure.in
blast/configure
blast/install.sh

blast/BlastLib/Makefile.in

Suppose you have just checked out (or updated) your complete blast software
distribution in /home/JohnDoe/blast using cvs. You want to compile the code
in one place and put it into a third location when you are done.

mkdir /home/JohnDoe/compile <-- you will compile here
mkdir /home/JohnDoe/install <-- installation will reside here

cd /home/JohnDoe/compile

Now invoke the configure script from the source tree:

../blast/configure --prefix=/home/JohnDoe/install

This means that you will compile it here (in ~/compile), and you wish to
install the stuff in ~/install. The following files will appear (note
output on your screen to see what is going on in the background):

config.status
config.log
config.cache
Makefile.inc
Makefile
BlastLib/Makefile

Note that the ".in" stuff is gone: you are left with config's log files
(which are useful in its own way), as well as with "real" Makefiles which
you can use to say "make". Say it from your compilation directory:

make

This make should jump into BlastLib, compile it, and exit the directory.
(When more directories are added, make goes through all of them. If
everything is configured properly, there is no need to think about which
directory you need to recompile first if you changes one thing and which
one if you change something else. One of the advantages of this tool is
that the dependencies should be resolved automatically.) Finally, say

make install

This should put BlastLib libraries (libBlast.so, libGeom.so, libRR2000.so)
into ~/install/lib and binaries (nsed, s, quick and count) into the
~/install/bin directory. You can now invoke these commands from
anywhere without any need to set up a LD_LIBRARY_PATH variable
since the -- one and only -- correct shared-library search path
was defined during the linking process. You're done.

Beginner++
----------

I have tested all this on my RH6.2, and I realise I might have overlooked
several things which should in general not taken for granted, e.g. the
location of the root package, which is usually /cern/root. Suppose you
want to port BlastLib to a different platform where root resides elsewhere.
One way to deal with it is through environmental variables, which are
a nuisance. "configure" can be made to perform this selection as well.
To see how this comes about and change it if necessary, you will need
to mess with configure.in.

There is a part of the code in it which says

AC_SUBST(ROOTSYS)
AC_ARG_WITH(cernlib,
            [ --with-rootsys=dir use the Root system found in DIR],
            ROOTSYS="${withval}")
if test -z ""${ROOTSYS} ; then
   test -d /cern/root && ROOTSYS=/cern/root
fi

This means two things: "configure" first looks for root in /cern/root.
If it does not find it, it will just skip it and compilation will
inevitably fail at some stage. However, the default /cern/root can be
changed in two ways: by adding new paths in the "test" statements, or by
specifying it on the command line. For example, if JackDoe put his
root stuff into /stupid/location/root, he could say

../blast/configure --prefix=/home/JackDoe/install \
                   --with-rootsys=/stupid/location/root

But is the search paths in "test" statements are rich enough and "know"
all architectures, ideally, all one needs to change when transiting
to a different platform are the entries at the bottom of configure.in:

case "$host" in
i*86-*linux*)
        XLIBS='-L/usr/X11R6/lib -lXpm -lX11'
        CXXFLAGS='-g -D_REENTRANT'
        SHFLAGS='-shared -Wl,-soname,'
        LINKER='-Xlinker -rpath -Xlinker'
        ;;
*)
        echo "unknown architecture"
        exit
        ;;
esac

If I want to compile the codes on an e.g. HP-UX, on which compilers
take different flags and libraries reside in different "standard" places,
I should add something of this sort into the "$host$ case clause:

*-hp-hpux*)
        XLIBS='-L/usr/localX11R6/lib -lXpm -lX11'
        CXXFLAGS='-g -D_REENTRANT'
        SHFLAGS='-fPIC'
        LINKER='-Xlinker -rpath -Xlinker'
        ;;

You get the message.

If my "demo version" fails to compile or run on your machine, it could be
that it is because of the exactly those tiny differences between platforms
which are not covered in the configure.in and corresponding Makefile.in's.
But once this is accomplished and optimised, it works quite nicely.

Should you become enthusiastic about autoconf, I would encourage
those who keep a watchful eye over a given portion of the distribution
to help and convert their Makefiles into Makefile.in's.

Simon

-- 
  Simon Sirca
  MIT-LNS, Room 26-402                 Tel: +1 617 258-5438
  77 Massachusetts Avenue              Fax: +1 617 452-5950
  Cambridge, MA 02139-4307, USA        URL: http://pierre.mit.edu/~sirca



This archive was generated by hypermail 2.1.2 : Mon Feb 24 2014 - 14:07:28 EST