-
Oliver Sander authored
[[Imported from SVN: r5493]]
Oliver Sander authored[[Imported from SVN: r5493]]
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: