Skip to content
Snippets Groups Projects
buildsystem.tex 41.39 KiB
\documentclass[11pt,a4paper,headinclude,footinclude,DIV16,normalheadings]{scrartcl}
%\usepackage[today,nofancy]{svninfo}
\usepackage[automark]{scrpage2}
\usepackage[ansinew]{inputenc}
%\usepackage{german}
%\usepackage{bibgerm}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{theorem}
\usepackage{pst-all}
\usepackage{color}
\usepackage{listings}
\lstset{language=bash, basicstyle=\normalfont\ttfamily\scriptsize,
  keywordstyle=\color{black}\bfseries, tabsize=4,
  stringstyle=\ttfamily, commentstyle=\it, extendedchars=true}
\usepackage{hyperref}
\usepackage{makeidx}
\usepackage{xspace}

\usepackage{graphicx}

\newtheorem{lst}{Listing}
\newtheorem{remark}{Remark}[section]

\newcommand{\dune}{\texttt{DUNE}\xspace}
\newcommand{\autoconf}{\texttt{autoconf}\xspace}
\newcommand{\automake}{\texttt{automake}\xspace}
\newcommand{\autogen}{\texttt{dune-autogen}\xspace}
\newcommand{\libtool}{\texttt{libtool}\xspace}
\newcommand{\configure}{\texttt{configure}\xspace}
\newcommand{\configureac}{\texttt{configure.ac}\xspace}
\newcommand{\makefile}{\texttt{Makefile}\xspace}
\newcommand{\makefilein}{\texttt{Makefile.in}\xspace}
\newcommand{\makefileam}{\texttt{Makefile.am}\xspace}
\newcommand{\dunecommon}{\texttt{dune-common}\xspace}
\newcommand{\duneistl}{\texttt{dune-istl}\xspace}
\newcommand{\dunegrid}{\texttt{dune-grid}\xspace}
\newcommand{\dunefem}{\texttt{dune-fem}\xspace}
\newcommand{\dunedisc}{\texttt{dune-disc}\xspace}
\newcommand{\dunegridhowto}{\texttt{dune-grid-howto}\xspace}
\newcommand{\dunegriddevhowto}{\texttt{dune-grid-dev-howto}\xspace}
\newcommand{\dunecontrol}{\texttt{dunecontrol}\xspace}
\newcommand{\duneproject}{\texttt{duneproject}\xspace}
\newcommand{\dunemodule}{\texttt{dune.module}\xspace}
\newcommand{\make}{\texttt{make}\xspace}
\newcommand{\topsrc}{\$(top\_srcdir)}

\newcommand{\executable}[1]{{\em #1}\xspace}

\pagestyle{scrheadings}

\title{The DUNE Buildsystem HOWTO}

\author{Christian Engwer$^\ast$ \and
Felix Albrecht$^\dagger$}

%\date{\svnToday}
\date{March 1 2009}

\publishers{%
\vspace{10mm}
{\normalsize $^\ast$Interdisziplin\"ares Zentrum f\"ur Wissenschaftliches Rechnen,
Universit\"at Heidelberg,\\
Im Neuenheimer Feld 368, D-69120 Heidelberg, Germany}\\
%
\bigskip
{\normalsize $^\dagger$Institut f\"ur Numerische und Angewandte Mathematik,
Westf\"alische Wilhelms-Universit\"at M\"unster,\\
Einsteinstr. 62, D-48149 M\"unster, Germany}\\
%
\bigskip
{\normalsize \texttt{\url{http://www.dune-project.org/}}}\\
}

\begin{document}

\maketitle
\tableofcontents
\pagebreak

\section{Getting started}\label{section::getting_started}

\textbf{TODO: How do I build the grid howto?}

\section{Creating your own \dune module}\label{section::creating_dune_module}

This section tells you how to begin working with \dune without explaining any
further details. For a closer look on \duneproject, see section
\ref{section::creating_new_dune_project}.\\

Once you have downloaded all the \dune modules you are interested in, you probably
wonder ``How do I start working with \dune?'' It is quite easy.
Let us assume you have a terminal open and are inside a directory containing
some \dune modules. Let us say
 
\begin{lstlisting}[language=make]
ls -l
\end{lstlisting}
produces something like:

\begin{lstlisting}[language=make]
dune-common/
dune-grid/
config.opts
\end{lstlisting}

There is no difference between a \dune module you have downloaded from
the web and modules you created yourself.
\dunecontrol takes care of configuring your project and creating the
correct \texttt{Makefile}s (so you can easily link and use all the other \dune
modules). It can be done by calling
 
\begin{lstlisting}[language=make]
./dune-common/bin/duneproject
\end{lstlisting}

\emph{Note:} In case you are using the unstable version
\dune you should be aware that the buildsystem may change,
just like the source code. Therefore it might be that
\texttt{duneproject} is not up to date with the latest changes. \\

After calling \duneproject, you have to provide a name for your project
(without whitespace), e.g., \texttt{dune-foo}. 
The prefix \texttt{dune-} is considered good practice, but it is not
mandatory.
You are then asked to provide a
list of all modules the new project should depend on (this will be
something like \dunecommon \dunegrid, etc.). At last, you should provide
the version of your project (e.g., \texttt{0.1}) and your email address.
\duneproject now creates your new project which is a folder with the name of your project,
containing some files needed in order to work with \dune.
In our example,
 
\begin{lstlisting}[language=make]
ls -l dune-foo/
\end{lstlisting}
should produce something like

\begin{lstlisting}[language=make]
configure.ac
dune.module
dune-foo.cc
Makefile.am
README
\end{lstlisting}

You can now call \dunecontrol for your new project, as you would for any other \dune module. If you have a \texttt{config.opts}\xspace
file configured to your needs (see e.g. the ``Installation Notes'' on
\texttt{www.dune-project.org}), a simple call of

\begin{lstlisting}[language=make]
./dune-common/bin/dunecontrol --module=dune-foo --opts=config.opts all
\end{lstlisting}
should call \autogen, \configure and \make for your
project and all modules your project depends on first.

\begin{remark}
Always call \dunecontrol from the directory containing \dunecommon.
\end{remark}

You can now  simply run

\begin{lstlisting}[language=make]
./dune-foo/dune-foo
\end{lstlisting}
which should produce something like

\begin{lstlisting}[language=make]
Hello World! This is dune-foo.
This is a sequential program.
\end{lstlisting}

If you want your \dune module to be useable by other people your design should
follow a certain structure. A good way to indicate that your module is set up
like the other \dune modules is by naming it with the prefix
\texttt{dune-}\xspace. 
Since your module should be concerned with a certain topic, you should give it
a meaningful name (e.g. \dunegrid is about grids). 

Our next step is to create the subfolders \texttt{doc/}\xspace,
\texttt{foo/}\xspace and \texttt{src/}\xspace in \texttt{dune-foo/}\xspace.\\
\texttt{foo/}\xspace will contain any headers that are of interest to other
users (like the subfolder \texttt{common/}\xspace in
\dunecommon, \texttt{grid/}\xspace in \dunegrid, etc.). Other users will have to
include those files if they want to work with them. Let's say we already have some interface implementation
in a file \texttt{bar.hh}\xspace. We put this one into the subfolder
\texttt{foo/}\xspace.\\
It is then convenient to collect whatever documentation exists about those
header files in \texttt{doc/}\xspace and since there should
at least exist some doxygen documentation we create the
subdirectory \texttt{doc/doxygen/}\xspace (see ``Coding Style'' in the
setion ``Developing Dune'' on \texttt{www.dune-project.org} for details).
We will need a \makefileam in
\texttt{doc/}\xspace and \texttt{doc/doxygen/}\xspace so we copy the
\makefileam from \texttt{dune-foo/Makefile.am}\xspace to
\texttt{dune-foo/doc/Makefile.am}. Since we also need
some other files for \texttt{doxygen}\xspace to work we just copy the
following files from e.g. \texttt{dune-grid/doc/doxygen/}\xspace to
\texttt{dune-foo/doc/doxygen/}\xspace:

\begin{lstlisting}[language=make]
Doxydep
Doxyfile
doxy-footer.html
doxy-header.wml
dune-doxy.css
mainpage
Makefile.am
modules
\end{lstlisting}

The \texttt{src/}\xspace subdirectory will contain the sources of your
implementation (usually at least one \texttt{.cc}\xspace file with a
\texttt{main} method). Since we already have such a file
(\texttt{dune\_foo.cc}), we move it to \texttt{src/}\xspace. We also need
a \makefileam in \texttt{src/}\xspace so we copy our \makefileam from
\texttt{dune-foo/Makefile.am}\xspace to
\texttt{dune-foo/src/Makefile.am}\xspace.\\
Of course we will have to edit those copies later on. But let's take a
look at the structure of our project now.

\begin{lstlisting}[language=make]
dune-foo/
-> configure.ac
-> doc/
   -> doxygen/
      -> Doxydep
      -> Doxyfile
      -> doxy-footer.html
      -> doxy-header.wml
      -> dune-doxy.css
      -> mainpage
      -> Makefile.am
      -> modules
   -> Makefile.am
-> dune.module
-> foo/
   -> bar.hh
-> Makefile.am
-> README
-> src/
   -> dune_foo.cc
\end{lstlisting}

Now all that's left to do is to edit those \texttt{Makefile.am}s, the
\configureac and some \texttt{doxygen} files.\\
First we open the file \texttt{dune-foo/Makefile.am}. Ignoring
comments, you should edit the file as follows:

\begin{lstlisting}[numbers=left,numberstyle=\tiny,numbersep=5pt,language=make]
EXTRA_DIST=dune.module

DIST_SUBDIRS = doc src

if BUILD_DOCS
SUBDIRS = doc src
else
SUBDIRS = src
endif

AUTOMAKE_OPTIONS = foreign 1.5

DISTCHECK_CONFIGURE_FLAGS = --with-dune=$(DUNEROOT) CXX="$(CXX)" CC="$(CC)"

include $(top_srcdir)/am/global-rules
\end{lstlisting}
Lines $5-9$ state that there are two relevant subdirectories
(in \texttt{doc/} and \texttt{src/}) if your module is being
configured without the \texttt{--disable-documentation} flag or just in
\texttt{src/} otherwise. Line 13 might look different on your
machine, and you should use the line from the original \makefileam in that
case.\\
We can leave \texttt{dune-foo/src/Makefile.am} nearly as it is, only the line 

\begin{lstlisting}[language=make]
EXTRA_DIST=dune.module
\end{lstlisting}
should be removed.\\

Now we have to tell \autogen something about the structure of
our project. This can easily be done by opening \texttt{dune-foo/configure.ac}
and editing just two lines.\\
Since we moved \texttt{dune\_foo.cc} into \texttt{src/} we have to tell
\configure where it is now. Therefore we change the line

\begin{lstlisting}[language=make]
AC_CONFIG_SRCDIR([dune_foo.cc])
\end{lstlisting}
to 

\begin{lstlisting}[language=make]
AC_CONFIG_SRCDIR([src/dune_foo.cc])
\end{lstlisting}

Also we have to tell \configure about all the \makefile{}s we need created.
We do this by editing the line

\begin{lstlisting}[language=make]
AC_CONFIG_FILES([Makefile])
\end{lstlisting}
For our example, we replace the above line with the following:

\begin{lstlisting}[language=make]
AC_CONFIG_FILES([Makefile
    src/Makefile
    doc/Makefile
    doc/doxygen/Makefile])
\end{lstlisting}

Now your module is nearly ready to being configured by \dunecontrol. Only the 
\texttt{doxygen} part is missing (in fact, configuring it with the
\texttt{--disable-documentation} flag would work from this point on).\\

To configure \texttt{doxygen} we have to edit two \texttt{Makefile.am}s and some
\texttt{doxygen} files. The first \makefileam to edit is of course
\texttt{dune-foo/doc/Makefile.am}. Ignoring comments again, the file should
look like:

\begin{lstlisting}[numbers=left,numberstyle=\tiny,numbersep=5pt,language=make]
SUBDIRS = doxygen

all: $(PAGES)

CURDIR=doc

BASEDIR=..

docdir=$(datadir)/doc/dune-foo

include $(top_srcdir)/am/webstuff

CLEANFILES = $(PAGES)

if ! BUILD_DOCS
dist-hook:
	echo "# No documentation included in distribution! " > $(distdir)/$(DOCUMENTATION_TAG_FILE)
endif

include $(top_srcdir)/am/global-rules
\end{lstlisting}

Now we can take a look at \makefileam in \texttt{dune-foo/doc/doxygen/}.
Since this one was copied from \dunegrid it should suffice to change all
occurrences of \texttt{grid} into \texttt{foo}. In \dune release 1.2 this
should be just the lines

\begin{lstlisting}[language=make]
doxygendir = $(datadir)/doc/dune-grid/doxygen
\end{lstlisting}
and

\begin{lstlisting}[language=make]
EXTRAINSTALL="$(DOXYGENINSTALL)" CURDIR="$(CURDIR)/dune-grid-html" install ; \
\end{lstlisting}
which have to be changed to 

\begin{lstlisting}[language=make]
doxygendir = $(datadir)/doc/dune-foo/doxygen
\end{lstlisting}
and

\begin{lstlisting}[language=make]
EXTRAINSTALL="$(DOXYGENINSTALL)" CURDIR="$(CURDIR)/dune-foo-html" install ; \
\end{lstlisting}
respectively.\\
Now \dunecontrol is ready to take care of building the documentation. But since
we copied some \texttt{doxygen} stuff from \dunegrid there are some
\texttt{doxygen} files left we have to take care of. These are
\texttt{Doxyfile}, \texttt{mainpage} and \texttt{modules}. You can edit the
latter two as you like. They will form the main page and the module page of the
\texttt{html} documentation of \texttt{doxygen}.\\
We are basically left to change all occurrences of \texttt{grid} in the
\texttt{Doxyfile} as well as some settings. If you open the file 
\texttt{dune-foo/doc/doxygen/Doxyfile} the first thing you should see is a line
like

\begin{lstlisting}[language=make]
PROJECT_NAME = dune-grid
\end{lstlisting}
which should obviously be changed into

\begin{lstlisting}[language=make]
PROJECT_NAME = dune-foo
\end{lstlisting}
to state the name of your module.

The next thing we're interested in are the lines

\begin{lstlisting}[language=make]
INPUT = mainpage \
        modules \
        ../../grid/modules \
        ../../grid
\end{lstlisting}
which should of course look like

\begin{lstlisting}[language=make]
INPUT = mainpage \
        modules \
        ../../foo
\end{lstlisting}

Then there are some settings of \dunegrid left which we probably don't want to
have. So we just comment all the following lines by just adding a \texttt{\#}
at the beginning of every line.

\begin{lstlisting}[language=make]
EXCLUDE = ../../grid/onedgrid \
          ../../grid/uggrid \
          ../../grid/test
\end{lstlisting}

\begin{lstlisting}[language=make]
EXAMPLE_PATH = ../../grid/io/file/dgfparser/test 
\end{lstlisting}

\begin{lstlisting}[language=make]
IMAGE_PATH = ../../grid/sgrid \
             ../../grid/yaspgrid \
             ../../grid/common \
             ../../grid/io/file/dgfparser/test \
             ../appl/refelements \
             ../refinement
\end{lstlisting}

Now we are done editing files and ready to configure the module without the
option\\ \texttt{--disable-documentation} (provided you have \texttt{doxygen} and
the necessary tools installed on your system).\\
After running

\begin{lstlisting}[language=make]
./dune-common/bin/dunecontrol --module=foo --opts=config.opts all
\end{lstlisting}
with a \texttt{config.opts} that enables documentation you should now find a
\texttt{html} \texttt{doxygen} documentation in
\texttt{dune-foo/doc/doxygen/html/index.html}.\\

If you take a look at the \dune core modules you will find a symlink
\begin{lstlisting}[language=make]
dune -> .
\end{lstlisting}
in each main folder. Its purpose is to allow inclusion directives like
\begin{lstlisting}[language=c++]
#include<dune/foo/bar.hh>
\end{lstlisting}
If you want header files from your module to be includable from other
modules you should have this link.  You can set it manually
by goint to your module directory \texttt{dune-foo/} and typing
\begin{lstlisting}[language=make]
ln -s . dune
\end{lstlisting}
You can also let \configure do this for you automatically if you include this line 
\begin{lstlisting}[language=make]
DUNE_SYMLINK
\end{lstlisting}
in your \configureac file.

\begin{remark}
 This mechanism is under discussion and may change in a future version of \dune.
\end{remark}



\section{The Structure of \dune}
\dune consists of several independent modules:
\begin{itemize}
\item \dunecommon
\item \dunegrid
\item \duneistl
\item \dunegridhowto
\item \dunegriddevhowto
\end{itemize}

Single modules can depend on other modules and so the \dune modules
form a dependency graph.  The build system has to track and resolve
these inter-module dependencies.

The build system is structured as follows:
\begin{itemize}
\item Each module is built using the GNU AutoTools.
\item Each module has a set of modules it depends on, these modules
  have to be built before building the module itself.
\item Each module has a file \dunemodule which holds dependencies and
  other information regarding the module.
\item The modules can be built in the appropriate order using the
  \dunecontrol script (shipped with \dunecommon)
\end{itemize}

The reasons to use the GNU AutoTools for \dune were the following
\begin{itemize}
\item We need platform independent build.
\item Enabling or disabling of certain features depending on
  features present on the system.
\item Creations of libraries on all platforms.
\item Easy creation of portable but flexible Makefiles.
\end{itemize}

The reasons to add the \dunecontrol script and the \dunemodule
description files were
\begin{itemize}
\item One tool to setup all modules (the AutoTools can only work on one
  module).
\item Automatic dependency tracking.
\item Automatic collection of command-line parameters (\configure needs
  special command-line parameters for all modules it uses)
\end{itemize}

\section{Building Single Modules Using the GNU AutoTools}

Software is generally developed to be used on multiple
platforms. Since each of these platforms has different compilers,
different header files, there is a need to write makefiles and build
scripts that work on a variety of platforms. The Free
Software Foundation (FSF), faced with this problem, devised a
set of tools to generate makefiles and build scripts that work on a
variety of platforms. These are the GNU AutoTools. 
If you have downloaded and built any GNU
software from source, you are familiar with the \configure script. The
\configure script runs a series of tests to get information about
your machine.

The autotools simplify the generation of portable Makefiles and
configure scripts.

\minisec{autoconf}

\autoconf is used to create the \configure script. \configure is
created from \configureac, using a set of \texttt{m4} files.

\begin{center}
\psset{unit=0.5mm}
\psset{linewidth=0.4pt}
\begin{pspicture}(140,50)
\put(-26,45){\parbox{40\unitlength}{\centering{}\configureac}}
\put(116,45){\parbox{40\unitlength}{\centering{}\tt{}m4/*.m4}}
\put(0,36)
{
  \psset{linewidth=1pt}
  \psline[linearc=4]{c-}(-2,2)(-2,-2)(67.5,-2)(67.5,-6)
  \psline[linearc=4]{c-}(137,2)(137,-2)(67.5,-2)(67.5,-6)
  \psline{->}(67.5,-5.5)(67.5,-20)
}
\put(72,22){\textit{\autoconf}}
\put(50,7){\parbox{40\unitlength}{\centering{}\configure}}
\end{pspicture}
\end{center}

How to write a \configureac for \dune is described in Sec.\,\ref{configure.ac}.

\minisec{automake}

\automake is used to create the \makefilein files (needed for
\configure) from \makefileam files, using a set of include files
located in a directory called \texttt{am}. These include files provide
additional features not provided by the standard \automake (see
Sec.\,\ref{am_includes}). The \texttt{am} directory is in the \dunecommon
module and each module intending to use one of these includes has to
have a symlink \texttt{am} that points to \texttt{dune-common/am}.
This link is usually created by \autogen (see Sec.\,\ref{autogen}).
\begin{center}
\psset{unit=0.5mm}
\psset{linewidth=0.4pt}
\begin{pspicture}(140,80)
\put(-26,75){\parbox{40\unitlength}{\centering{}\makefileam}}
\put(116,75){\parbox{40\unitlength}{\centering{}\tt{}am/*}}
\put(0,66)
{
  \psset{linewidth=1pt}
  \psline[linearc=4]{c-}(-2,2)(-2,-2)(67.5,-2)(67.5,-6)
  \psline[linearc=4]{c-}(137,2)(137,-2)(67.5,-2)(67.5,-6)
  \psline{->}(67.5,-5.5)(67.5,-20)
}
\put(72,52){\textit{\automake}}
\put(50,37){\parbox{40\unitlength}{\centering{}\texttt{Makefile.in}}}
\put(0,34)
{
  \psset{linewidth=1pt}
  \psline[linestyle=dashed,dash=1.5pt 1.5pt]{->}(67.5,0)(67.5,-14.5)
}
\put(72,25){\textit{\configure}}
\put(50,10){\parbox{40\unitlength}{\centering{}\texttt{Makefile}}}
\end{pspicture}
\end{center}

Information on writing a \makefileam is described in \ref{makefile.am}

\minisec{libtool}
\libtool is a wrapper around the compiler and
linker. It offers a generic interface for creating static and shared
libraries, regardless of the platform it is running on.

\libtool hides all the platform specific aspects of library creation
and library usage. When linking a library or an executable you (or
\automake) can call the compiler via \libtool. \libtool will then take
care of
\begin{itemize}
\item platform specific command-line parameters for the linker,
\item library dependencies.
\end{itemize}

\minisec{configure}
\label{configure}
\configure will run the set of tests specified in your \configureac.
Using the results of these tests configure can check that all
necessary features (libraries, programs, etc.) are present and can activate
and deactivate certain features of the module depending on what is
available on your system.

For example \configure in \dunegrid will search for the ALUGrid
library and  enable or disable \texttt{Dune::ALU3dGrid}.
This is done by writing a preprocessor macro \verb!#define HAVE_ALUGRID!
in the \texttt{config.h}
header file. A header file can then use an \verb!#ifdef! statement to
disable parts of the code that do not work without a certain
feature. This can be used in the applications as well as in the headers
of a \dune module.

The \texttt{config.h} file is created by \configure from a
\texttt{config.h.in} file, which is automatically created from the
list of tests used in the \configureac.

\subsection{Makefile.am}
\label{makefile.am}

\subsubsection{Overview}

Let's start off with a simple program \executable{hello} built from
\texttt{hello.c}. As \automake is designed to build and install a
package it needs to know

\begin{itemize}
\item what programs it should build,
\item where to put them when installing,
\item which sources to use.
\end{itemize}

The core of a \makefileam thus looks like this:

\begin{lstlisting}[language=make]
noinst_PROGRAMS = hello
hello_SOURCES = hello.c
\end{lstlisting}

This would build \executable{hello} but not install it when \texttt{make
  install} is called. Using \verb!bin_PROGRAMS! instead of
\verb!noinst_PROGRAMS! would install the \executable{hello}-binary into a
\texttt{\textit{prefix}/bin} directory.

Building more programs with several source files works like this

\begin{lstlisting}[language=make]
noinst_PROGRAMS = hello bye

hello_SOURCES = common.c common.h hello.c
bye_SOURCES = common.c common.h bye.c parser.y lexer.l
\end{lstlisting}

\automake has more integrated rules than the standard make, the example
above would automatically use yacc/lex to create
\texttt{parser.c/lexer.c} and build them into the {\em bye} binary.

Make-Variables may be defined and used as usual:

\begin{lstlisting}[language=make]
noinst_PROGRAMS = hello bye

COMMON = common.c common.h

hello_SOURCES = $(COMMON) hello.c
bye_SOURCES = $(COMMON) bye.c parser.y lexer.l
\end{lstlisting}

Even normal make-rules may be used in a \makefileam.

\minisec{Using flags}

Compiler/linker/preprocessor-flags can be set either globally:

\begin{lstlisting}[language=make]
noinst_PROGRAMS = hello bye

AM_CPPFLAGS = -DDEBUG

hello_SOURCES = hello.c
bye_SOURCES = bye.c
\end{lstlisting}

or locally:

\begin{lstlisting}[language=make]
noinst_PROGRAMS = hello bye

hello_SOURCES = hello.c
hello_CPPFLAGS = -DHELLO

bye_SOURCES = bye.c
bye_CPPFLAGS = -DBYE
\end{lstlisting}
The local setting overrides the global one, thus

\begin{lstlisting}[language=make]
hello_CPPFLAGS = $(AM_CPPFLAGS) -Dmyflags
\end{lstlisting}

may be a good idea.

It is even possible to compile the same sources with different flags:

\begin{lstlisting}[language=make]
noinst_PROGRAMS = hello bye

hello_SOURCES = generic-greeting.c
hello_CPPFLAGS = -DHELLO

bye_SOURCES = generic-greeting.c
bye_CPPFLAGS = -DBYE
\end{lstlisting}

Perhaps you're wondering why the above examples used
\texttt{AM\_CPPFLAGS} instead of the normal \texttt{CPPFLAGS}? The
reason for this is that the variables \texttt{CFLAGS},
\texttt{CPPFLAGS}, \texttt{CXXFLAGS} etc. are considered {\em user
  variables} which may be set on the commandline:

\begin{lstlisting}[language=make]
make CXXFLAGS="-O2000"
\end{lstlisting}

This would override any settings in Makefile.am which might be
necessary to build. Thus, if the variables should be set even if the
user wishes to modify the values, you should use the \texttt{AM\_*}
version. 

The real compile-command always uses both \texttt{AM\_\textit{VAR}} and
\texttt{\textit{VAR}}. Options that
autoconf finds are stored in the user variables (so that they may be
overridden) 

Commonly used variables are:
\begin{itemize}
\item \texttt{AM\_CPPFLAGS}: flags for the C-Preprocessor. This
  includes preprocessor defines like \texttt{-DNDEBUG} and include
  pathes like \texttt{-I/usr/local/package/include}
\item \texttt{AM\_CFLAGS}, \texttt{AM\_CXXFLAGS}: flags for the
  compiler (-g, -O, ...). One difference between these and the
  \texttt{CPPFLAGS} is that the linker will get
  \texttt{CFLAGS}/\texttt{CXXFLAGS} and \texttt{LDFLAGS} but not
  \texttt{CPPFLAGS}
\item \texttt{AM\_LDFLAGS} options for the linker
\item \texttt{LDADD}: libraries to link to a binary
\item \texttt{LIBADD}: libraries to add to a library
\item \texttt{SOURCES}: list of source-files (may include headers as well)
\end{itemize}

\minisec{Conditional builds}

Some parts of \dune only make sense if certain addon-packages were
found. autoconf therefore defines {\em conditionals} which automake can
use:

\begin{lstlisting}[language=make]
if OPENGL
  PROGS = hello glhello
else
  PROGS = hello
endif

hello_SOURCES = hello.c

glhello_SOURCES = glhello.c hello.c
\end{lstlisting}

This will only build the {\em glhello} program if OpenGL was found. An
important feature of these conditionals is that they work with any
make program, even those without a native {\em if} construct like GNU-make.

\minisec{Default targets}

An automake-generated Makefile does not only know the usual {\em all},
{\em clean} and {\em install} targets but also
\begin{itemize}
\item {\bf tags} travel recursively through the directories and create
  TAGS-files which can be used in many editors to quickly find where
  symbols/functions are defined (use emacs-format)
\item {\bf ctags} the same as "tags" but uses the vi-format for the tags-files
\item {\bf dist} create a distribution tarball
\item {\bf distcheck} create a tarball and do a test-build if it really works
\end{itemize}

\subsubsection{Building Documentation}
\label{am_includes}

If you want to build documentation you might need additional make
rules. \dune offers a set of predefined rules to create certain kinds
of documentation. Therefor you have to include the appropriate rules
from the \texttt{am/} directory. These rules are stored in the
\texttt{dune-common/am/} directory. If you want to use these any of
these rules in your \dune module or application you will have to
create a symbolic link to \texttt{dune-common/am/}. The creation of
this link should be done by the \autogen script.

\minisec{html pages}
Webpages are created from wml sources, using the program \texttt{wml}
(\texttt{\url{http://thewml.org/}}).\\
\texttt{\$(top\_srcdir)/am/webstuff} contains the necessary rules.

\hspace*{-2ex}\begin{minipage}{\textwidth}
\begin{lst}[File Makefile.am] \mbox{}
\lstinputlisting[language=make]{../Makefile.am}
\end{lst}
\end{minipage}

\minisec{\LaTeX documents}
In order to compile \LaTeX documents you can include
\texttt{\$(top\_srcdir)/am/latex}. This way you get rules for creation
of DVI files, PS files and PDF files.

\minisec{SVG graphics}
SVG graphics can be converted to png, in order to include them into
the web page. This conversion can be done using inkscape
(\texttt{\url{http://www.inkscape.org/}}).
\texttt{\$(top\_srcdir)/am/inkscape.am} offers the necessary rules.


\subsection{configure.ac}
\label{configure.ac}

\configureac  is a normal text file that contains several \autoconf
macros. These macros are evaluated my the \texttt{m4} macro processor
and transformed into a shell script.

\begin{lst}[File dune-common/configure.ac] \mbox{}
\lstinputlisting{../../configure.ac}
\end{lst}

We offer a set of macros that can be used in your \configureac:

\begin{itemize}
\item \texttt{DUNE\_CHECK\_ALL}
  runs all checks usually needed by a {\em \dune module}.
  It checks for all dependencies and suggestions and for their
  prerequisites.
  In order to make the dependencies known to \configure \autogen calls
  \texttt{dunecontrol m4create} and write a file
  \texttt{dependencies.m4}.
\item \texttt{DUNE\_SYMLINK}
  creates symlink \texttt{\$(top\_srcdir)/dune} $\rightarrow$
  \texttt{\$(top\_srcdir)}. The programming guidelines (\ref{guidelines})
  require that the include statements be like \texttt{\#include
    <dune/...>}. If your module has a directory structure
  \texttt{\topsrc/foo}, you will need such a link. However, you are
  encouraged to store the files directly in a directory structure
  \texttt{\topsrc/dune/foo} in order to avoid any inconvenience when
  copying the files. This will also eliminate the necessity for
  \texttt{DUNE\_SYMLINK}.
\item \texttt{DUNE\_AUTOBUILD\_FLAGS}
  adds configure flags needed to create log files for
  \texttt{dune-autobuild}. If you want to add your module to the
  \texttt{dune-autobuild} system, you have to call this macro.
\item \texttt{DUNE\_SUMMARY\_ALL}
  prints information on the results of all major checks run by
  \texttt{DUNE\_CHECK\_ALL}.
\end{itemize}

\texttt{DUNE\_CHECK\_ALL} and \texttt{DUNE\_CHECK\_ALL\_M} define certain
variables that can be used in the \configure script or in the
\makefileam:

\begin{itemize}
\item \texttt{DUNE\textit{\,MODULE\,}\_CPPFLAGS}
\item \texttt{DUNE\textit{\,MODULE\,}\_LDFLAGS}
\item \texttt{DUNE\textit{\,MODULE\,}\_LIBS}
\item \texttt{DUNE\textit{\,MODULE\,}ROOT}
\end{itemize}

The last step to a complete \configureac is that you tell autoconf
which files should be generated by \configure. Therefor you add an
\texttt{AC\_CONFIG\_FILES([\textit{WhiteSpaceSeparatedListOfFiles}])}
statement to your \configureac. The list of files should be the list
of files that are to be generated, not the input -- i.e. you would
write
\begin{lstlisting}[language=make]
AC_CONFIG_FILES([Makefile doc/Makefile])
\end{lstlisting}
end not
\begin{lstlisting}[language=make]
AC_CONFIG_FILES([Makefile.in doc/Makefile.in])
\end{lstlisting}
After you told \autoconf which files to create you have to actually
trigger their creation with command \texttt{AC\_OUTPUT}

\subsection{dune-autogen}
\label{autogen}

The \autogen script is used to bring the freshly checked out module
into that state that you expect from a module received via the
tarball. That means it runs all necessary steps so that you can call
\configure to setup your module. In the case of \dune this means that
\autogen runs
\begin{itemize}
\item \texttt{libtoolize} (prepare the module for \libtool)
\item \texttt{dunecontrol m4create} (create an m4 file containing the
  dependencies of this module)
\item \texttt{aclocal} (collect all \autoconf macros needed for this module)
\item \texttt{autoheader} (create the \texttt{config.h.in})
\item \texttt{automake} (create the \makefilein)
\item \texttt{autoconf} (create \configure)
\end{itemize}

If needed it will also create the symbolic link to the
\texttt{dune-common/am/} directory (see \ref{am_includes}).

\subsection{m4 files}
\label{m4files}

\texttt{m4} files contain macros which are then composed into
\configure and are run during execution of \configure.

\minisec{private m4 macros}

You can add new tests to configure by providing additional macro files
in the directory \texttt{module/m4/}.

\minisec{dependencies.m4}

\texttt{\topsrc/dependencies.m4} hold all information about the
dependencies and suggestions of this module. It is an automatically
generated file. It is generated by \texttt{dunecontrol m4create}.

For each dependencies of your module \texttt{\emph{MODULE}\_CHECKS}
and \texttt{\emph{MODULE}\_CHECK\_MODULE} is called. Last
\texttt{\emph{MODULE}\_CHECKS} is called for your module, in order to
check all prerequisites for your module.

What you just read implies that you have to provide the two macros
\texttt{\emph{MODULE}\_CHECKS} and
\texttt{\emph{MODULE}\_CHECK\_MODULE} for your module. These should be
written to a \texttt{m4/*.m4} file.

Here follows an example for the module \texttt{dune-foo}:

\begin{lstlisting}
AC_DEFUN([DUNE_FOO_CHECKS])
AC_DEFUN([DUNE_FOO_CHECK_MODULE],[
  DUNE_CHECK_MODULES([dune-foo],        dnl module name
                     [foo/foo.hh],      dnl header file
                     [Dune::FooFnkt])   dnl symbol in libdunefoo
])
\end{lstlisting}

The first one calls all checks required to make use of
\texttt{dune-foo}. The dependency checks are not to be included, they
are run automatically. The second macro tells how to check for your
module. In case you are only writing an application and don't want to
make this module available to other modules, you can just leave it
empty. If you have to provide some way to find your module. The
easiest is to use the \texttt{DUNE\_CHECK\_MODULES} macro, which is
defined in \texttt{dune-common/m4/dune.m4}.

\section{Building Sets of Modules Using \dunecontrol}
\label{dunecontrol}
\dunecontrol helps you building the different \dune modules in the
appropriate order. Each module has a \dunemodule file which contains
information on the module needed by \dunecontrol. 

\dunecontrol searches for \dunemodule files recursively from where you
are executing the program. For each \dune module found it will execute
a \dunecontrol command. All commands offered by \dunecontrol have a
default implementation. This default implementation can be overwritten
and extended in the \dunemodule file.

The commands you are interested in right now are
\begin{itemize}
\item \texttt{autogen} runs \autogen for each module. A list of
  directories containing \dunemodule files and the parameters given on
  the commandline are passed as parameters to \autogen.
\item \texttt{configure} runs \configure for each
  module. \texttt{--with-dune\textit{module}} parameters are created
  for a set of known \dune modules.
\item \texttt{make} runs \make for each module.
\item \texttt{all} runs \autogen, \configure and \make for each module.
\end{itemize}

In order to build \dune the first time you will need the \texttt{all}
command. In pseudo code \texttt{all} does the following:
\begin{lstlisting}[language=Perl]
foreach ($module in $Modules) {
  foreach (command in {autogen,configure,make) {
    run $command in $module
  }
}
\end{lstlisting}

This differs from calling
\begin{lstlisting}
dunecontrol autogen
dunecontrol configure
dunecontrol make
\end{lstlisting}
as it ensures that i.e. \dunecommon is fully built before \configure
is executed in \dunegrid. Otherwise \configure in \dunegrid would
complain that \texttt{libcommon.la} from \dunecommon is missing.

Further more you can add parameters to the commands; these parameters
get passed on to the program being executed. Assuming you want to call
\texttt{make clean} in all \dune modules you can execute
\begin{lstlisting}
dunecontrol make clean
\end{lstlisting}

\minisec{opts files}
You can also let \dunecontrol read the command parameters from a file.
For each command you can specify parameters. The parameters are stored
in a variable called \texttt{\textit{COMMAND}\,\_FLAGS} with
\texttt{\textit{COMMAND}} written in capital letters.

\begin{lst}[File example.opts] \mbox{}
\lstinputlisting{../example.opts}
\end{lst}

When you specify an opts file and command line parameters
\begin{lstlisting}
dunecontrol --opts=some.opts configure --with-foo=bar
\end{lstlisting}
\dunecontrol will ignore the parameters specified in the opts file and
you will get a warning.

\minisec{environment variables}
You can further control the behavior of \dunecontrol by certain
environment variables.
\begin{itemize}
\item \texttt{DUNE\_CONTROL\_PATH} specifies the paths, where
  \dunecontrol is searching for modules. All entries have to be colon
  separated and should point to either a directory (which is search
  recursively for \texttt{dune.module} files) or a directly
  \texttt{dune.module} file.
\item \texttt{DUNE\_OPTS\_FILE} specifies the opts file that should be
  read by \dunecontrol. This variable will be overwritten by the
  \texttt{--opts=} option.
\item \texttt{MAKE} tells \dunecontrol which command to invoke for
  'make'. This can be useful for example, if you want to use
  \texttt{\textit{gmake}} as a make drop-in.
\item \texttt{GREP} tells \dunecontrol which command to invoke for 'grep'.
\end{itemize}

\minisec{dune.module}

The \dunemodule file is split into two parts. First we have the
parameter section where you specify parameters describing the module.
Then we have the command section where you can overload the default
implementation of a command called via \dunecontrol.

\begin{lst}[File dune.module] \mbox{}
\begin{lstlisting}
# parameters for dune control
Module: dune_grid
Depends: dune_common
Suggests: UG Alberta Alu3d

# overload the run_configure command
run_configure () {
  # lets extend the parameter list $CMD_FLAGS
  if test "x$HAVE_UG" == "xyes"; then
    CMD_FLAGS="$CMD_FLAGS \"--with-ug=$PATH_UG\""
  fi
  if test "x$HAVE_Alberta" == "xyes"; then
    CMD_FLAGS="$CMD_FLAGS \"--with-alberta=$PATH_Alberta\""
  fi  
  if test "x$HAVE_Alu3d" == "xyes"; then
    CMD_FLAGS="$CMD_FLAGS \"--with-alugrid=$PATH_Alu3d\""
  fi
  # call the default implementation
  run_default_configure
}
\end{lstlisting}
\end{lst}

The parameter section will be parsed by \dunecontrol will effect
i.e. the order in which the modules are built. The parameters and
their values are separated by colon. Possible parameters are
\begin{itemize}
\item \texttt{Module} (\em required\em) is the name of the module. The
  name is of the form \texttt{[a-zA-Z0-9\_]+}.
\item \texttt{Depends} (\em required\em) takes a space separated list
  of required modules. This module is not functional without these
  other modules.
\item \texttt{Suggests} (\em optional\em) takes a space separated list
  of optional modules. This module is functional without these
  other modules, but can offer further functionality if one or more of
  the suggested modules are found.
\end{itemize}

The command section lets you overload the default implementation
provided by \dunecontrol. For each command \dunecontrol call the
function \texttt{run\_\textit{command}}. The parameters from the
commandline or the opts file are store in the variable
\texttt{\$CMD\_FLAGS}. If you just want to create additional parameters
you can add these to \texttt{\$CMD\_FLAGS} and then call the default
implementation of the command via
\texttt{run\_default\_\textit{command}}.

\section{Creating a new \dune project}\label{section::creating_new_dune_project}

From a buildsystem point of view there is no difference between a \dune
application and a \dune module.\\

\dune modules are packages that offer a certain functionality that can
be used by \dune applications. Therefore \dune modules offer libraries
and/or header files. A \dune module needs to comply with certain rules
(see \ref{guidelines}).

Creating a new \dune project has been covered in detail in 
\ref{section::creating_dune_module} using \texttt{duneproject} to take
work off of the user. This is also the recommended way to start a new project. 
If for whatever reasons you do not wish to use \duneproject here is 
the bare minimum you have to provide in order to create a new project:
\begin{itemize}
\item a \dunemodule file\\
  Usually you will only need to specify the parameters \texttt{Module}
  and \texttt{Depends}.
\item \emph{Note:} an \autogen script is \emph{not} needed any more!
\item a basic m4 file\\
  You need to provide two macros \texttt{\emph{MODULE}\_CHECKS}
  and \texttt{\emph{MODULE}\_CHECK\_MODULE}.
\item a \configureac file\\
  Have look at the \configureac in \dunegrid for example. The most
  important part is the call to \texttt{DUNE\_CHECK\_ALL} which
  runs all checks needed for a \dune module, plus the checks for the
  dependencies.
\end{itemize}

\section{Dune module guidelines}\label{section::dune_module_guidelines}
\label{guidelines}

A \dune module should comply with the following rules:
\begin{itemize}
\item Documentation is located under \texttt{doc/} and gets
  web-installed under \texttt{BASEDIR/doc/}.
\item \automake includes are located in \dunecommon. To use them, you
  will have to make a symbolic link to \texttt{dune-common/am/} (see
  \ref{am_includes}). The symlink creation should be handled by the
  \autogen (see \ref{autogen}).
\item The \texttt{am/} directory does not get included in the tarball.
\item Header files that can be used by other \dune modules should be
  accessible via \verb!#include <dune/foo/bar.hh>!. In order to work
  with a freshly checkout version of your module you will usually need
  to create a local symbolic link \texttt{dune ->
    \textit{module-directory/}}. This link gets created by the
  \texttt{DUNE\_SYMLINK} command in your \configureac. When running
  \texttt{make install} all header files should be installed into
  \texttt{\textit{prefix}/include/dune/}.
\end{itemize}

\section{Further documentation}

\minisec{automake \& Makefile.am}
\texttt{\url{http://www.gnu.org/software/automake/manual/}}\\
The \automake manual describes in detail how to write and maintain a
\makefileam and the usage of \automake.

\minisec{autoconf \& configure.ac}
\texttt{\url{http://www.gnu.org/software/autoconf/manual/}}\\
The \autoconf manual covers the usage of \autoconf and how to write
\configure.ac files (sometimes they are called \texttt{configure.in}).

\minisec{Autoconf Macro Archive}
\texttt{\url{http://autoconf-archive.cryp.to/}}\\
The Autoconf Macro Archive provides macros that can be integrated in
your \configureac in order to search for certain software. These
macros are useful to many software writers using the autoconf tool, but too
specific to be included into autoconf itself.

\minisec{libtool}
\texttt{\url{http://www.gnu.org/software/libtool/manual.html}}\\
The \libtool manual offers further information on the usage of
\libtool package and gives a good overview of the different
problems/aspects of creating portable libraries.

\minisec{autobook}
\texttt{\url{http://sources.redhat.com/autobook/}}\\
The autobook is a complete book describing the GNU toolchain
(\autoconf, \automake and \libtool). It contains many recipes on how
to use the autotools. The book is available as an online 
version.

\minisec{dune-project}
\texttt{\url{http://www.dune-project.org/}}\\
The official homepage of \dune.

\end{document}

%%% Local IspellDict: "american"
%%% Local Variables: 
%%% mode: latex
%%% TeX-master: t
%%% End: