\section{Programmierbeispiel}
Im vorliegenden Abschnitt werden (nun endlich) \textit{Autoconf} und
\textit{Automake} als Entwicklerwerkzeuge betrachtet. An Hand des hier
behandelten Beispiels sollen diese beiden Tools aus der Sicht eines
Entwicklers gezeigt werden, wobei sichtbar werden sollte, wie stark die
Werkzeuge den Entwicklern beim Erstellen eines Pakets unterst\"utzen und den
Erstellungsprozess eines Sourcecodepakets erleichtern. Zugegebener Massen mag
der Anfang mit den Tools etwas undurchscheinbar erscheinen, der Leser sollte
sich jedoch nicht davon abbringen lassen.

\subsection{hello.c}
Es soll eine sehr einfache Applikation, in C geschrieben, erstellt
werden, die nichts anderes durchf\"uhren soll, als ``Hallo Welt''
auszugeben. Der Code f\"ur das Programm wird einfach in einer Datei
``hello.c'' gespeichert. Dabei soll der Code so entworfen sein, dass
er mit den \textit{Autoconf}-\"ublichen Mitteln zu einem Paket gepackt
werden kann.

\begin{verbatim}
#include <stdio.h>

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

int main( int argc, char ** argv )
{
#ifdef CONFIG_REPEAT
   int i;
   for( i = 0; i < 10; i++ )
#endif
      puts( "Hello World!" );

   return 0;
}
\end{verbatim}

Die Headerdatei \texttt{stdio.h} wird wegen der im Code verwendeten
\texttt{puts}-Funktion inkludiert (siehe \texttt{man~3~stdio}). Eine kleine
Erweiterung des Programms soll gegeben sein, um eine Demonstration f\"ur
\textit{Autoconf} zu haben. Wird zum Zeitpunkt des Kompilierens die
Pr\"aprozessorvariable ``CONFIG\_REPEAT'' definiert, so soll der auszugebende
String zehn mal auf dem Bildschirm erscheinen. Dazu ist der daf\"ur
verantwortliche Code durch die Pr\"aprozessorvariable isoliert.  Die Datei
\texttt{config.h} wird nur gegebenen Falls eingebunden. In ihr befinden
Definitionen, die sich von Kompilation zu Kompilation unterscheiden k\"onnen,
wie z.B. die Definition von ``CONFIG\_REPEAT''.  Ansonsten sind im Quelltext
keine Besonderheiten.

\subsection{Files}
\label{sec:Files}
Da der Quellcode f\"ur das Programm geschrieben ist, ist es an der
Zeit das Skript namens ``configure'' zu erstellen. Dabei ist es wichtig zu
verstehen welche zus\"atzlichen Dateien ben\"otigt werden, um aus
``hello.c'' mit Hilfe von \textit{Autoconf} und \textit{Automake} ein
richtiges Softwarepaket zu erstellen. Die im Folgenden aufgelisteten
Dateien werden von einem \textit{Autotools}-konformen Paket ben\"otigt.

\begin{description}
\item[configure.in] enth\"alt die Definitionen, mit deren Hilfe
  \textit{Autoconf} das ``configure''-Skript erstellt. Diese Datei wird vom
  Entwickler selbst geschrieben.\footnote{Seit \textit{Autoconf} Version 2.50
    wird in den GNU Manuals zu \textit{Autoconf} und \textit{Automake} von
    ``configure.ac'' gesprochen. Dies ist der neue Name der Datei.  Allerdings
    wird der Name ``configure.in'' immer noch aus Kompatibilit\"atgr\"unden
    unterst\"utzt und wird immer noch sehr h\"aufig vorgefunden.}
  
\item[Makefile.am] enth\"alt die Definitionen, mit deren Hilfe
  \textit{Automake} die sog. ``Makefile.in'' erstellt, aus welcher letztlich
  mittels ``configure'' die entscheidende ``Makefile'' wird.
  
\item[config.h.in] ist optional. Ist jedoch die vorliegende Software zur
  Kompilierzeit konfigurierbar (wie bspw. im vorliegenden Beispiel
  mittels CONFIG\_REPEAT), ist es sinnvoll die Konfiguration mittels
  ``config.h.in''  aufzuziehen.

\item[``Maintainerfiles''] Es gibt Dateien, die nicht unbedingt
  notwendig sind, um ``Makefile'' und ``configure'' zu
  erstellen, jedoch aber Bestandteil eines jeden Softwarepakets sein
  sollten. Fehlen die Dateien ``NEWS'', ``README'', ``AUTHORS'' und
  ``ChangeLog'', so beklagt sich \textit{Automake} \"uber ihre Abwesenheit.
\end{description}

Nach dem der Quellcode f\"ur das Programm in nur einer Datei ist, sollte somit
``hello.c'' zur Zeit die einzige Datei in Projektverzeichnis sein.  Die
``Maintainerfiles'' in obiger Auflistung sollen hier nicht von gro"ser
Bedeutung sein und werden deshalb mit den ``touch'' Befehl angelegt:
\begin{verbatim}
$ pwd
/home/pete/hello
$ touch NEWS README AUTHORS ChangeLog
$ ls -F
AUTHORS  ChangeLog  NEWS  README  hello.c
\end{verbatim}

Die beiden Dateien ``configure.in'' und ``Makefile.am'' spielen bei
den \textit{Autotools} eine zentrale Rolle. Zwischen den beiden Dateien besteht
ein impliziter Zusammenhang. Sehr vereinfacht dargestellt k\"onnte man ihn
wie folgt darstellen (dabei ist in eckigen Klammern das jeweils
auszuf\"uhrende Programm angegeben): 

\begin{verbatim}
(1)                           [autoconf]
configure.in ------------------------------ > configure

(2)                           [automake]
configure.in + Makefile.am ---------------- > Makefile.in

(3)                           [configure]
Makefile.in ------------------------------- > Makefile
\end{verbatim}

Im logisch ersten Schritt wird die Datei ``configure.in'' vom Programmierer
geschrieben, woraus mittels \textit{Autoconf} das Skript ``configure''
erstellt wird. Dieses Skript ist oft \"uber 4000 Zeilen lang, w\"ahrend die
hier im Beispiel vorgestellte Datei ``configure.in'' (der Quellcode f\"ur
``configure'') gerade mal 25 Zeilen haben wird.

Als zweites ben\"otigt der Programmierer die Datei ``Makefile.am''.  Diese
beschreibt unter anderem in sehr einfacher Form, was f\"ur Programme erstellt
werden sollen und welche Quelldateien daf\"ur jeweils notwendig sind. Da
bestimmte Definitionen f\"ur \textit{Automake} auch aus den Definitionen in
``configure.in'' hervorgehen, werden beide Dateien ben\"otigt, um eine
``Makefile.in'' zu erstellen. Auch hier ist \textit{Automake} eine gro"se
Hilfe, denn die generierte Datei wird \"uber 500 Zeilen haben, w\"ahrend die
von Hand geschriebene Datei zwei Zeilen lang sein wird.

Im logisch letzten Schritt (3) wird mittels ``configure'' mit optionalen
Parametern eine ``Makefile'' erstellt, die sich aus den Definitionen in der
Vorlage ``Makefile.in'' und den aus der Umgebung festgestellten
Systemeigenschaften ableitet. Jedgliche weitere Arbeit \"ubernimmt das
Programm ``Make''.

\subsection{Makefile.am}
Eine ``Makefile'' beschreibt die Art und Weise, sowie die Reihenfolge, wie ein
Programm erstellt werden soll. Je mehr Quelldateien ein Programm als Quelle
hat, um so mehr Abh\"angigkeiten bestehen zwischen diesen Dateien. Dies gilt
es beim Erstellen zu ber\"ucksichtigen. Das ist jedoch die Aufgabe des
Programms ``Make'', welches die ``Makefile'' als Eingabedatei
abarbeitet. Eine korrekte und alle Abh\"angigkeiten ber\"ucksichtigende
``Makefile'' von Hand zu erstellen ist gerade bei gr\"osseren Projekten nicht
gerade trivial. Das manuelle Erstellen von gro"seren ``Makefile''s ist von
Projekt zu Projekt recht \"ahnlich, erm\"udend und somit recht
fehleranf\"allig.

Abhilfe schafft \textit{Automake}, welches eine ``Makefile.am'' einliest und
daraus eine ``Makefile.in'' erstellt. Die ``Makefile.am'', welche der
Programmierer von Hand erstellt, ist sehr einfach und \"ubersichtlich. Die
generierte ``Makefile.in'' ist eine Vorlage f\"ur ``configure'', welches in
der Datei einige Ersetzungen durchf\"uhrt und damit die gew\"unschte
``Makefile'' erstellt.

Die Syntax der ``Makefile.am'' ist sehr einfach und intuitiv.
N\"aheres dazu ist im \textit{Automake}-Manual \cite{AutomakeFSF}
beschrieben, welches es in verschiedenen Formaten gibt. Die
``Makefile.am'' im vorliegenden Beispiel besteht aus nur zwei Zeilen:

\begin{verbatim}
bin_PROGRAMS = hello
hello_SOURCES = hello.c
\end{verbatim}

Die erste Zeile meldet \textit{Automake}, dass ein Program namens ``hello''
erstellt werden soll, w\"ahrend die zweite, die Quelldateien angibt, die zur
Erstellung von ``hello'' ben\"otigt werden. Um alles andere k\"ummert sich
\textit{Automake}.


\subsection{configure.in}
Es fehlt noch die ``configure.in'', um das Paket startklar zu
machen. \textit{Autoconf} liest diese Datei ein, expandiert dort die stehenden
Makros und erstellt letztlich ein portables Shell-Skript namens
``configure''.

Die Eingabesprache von \textit{Autoconf} ist nicht besonders complex,
allerdings ist der Anfang mit \textit{Autoconf} nicht gerade leicht.
Im Wesentlichen werden Makros verwendet, deren Bedeutung man in
\cite{AutoconfFSF} nachlesen kann. Das Manual ist sehr empfehlenswert,
da es den Leser in einer Art Tutorial mit \textit{Autoconf} bekannt
macht.

Einen sehr guten Anfang bietet das Tool ``Autoscan''. Ruft man es ohne
Kommandozeilenparameter auf, so wird das aktuelle Verzeichnis genommen, um die
darin enthaltenen Dateien zu durchsuchen und eine Datei ``configure.scan''
anzulegen. Diese Datei ist ein Vorschlag f\"ur eine ``configure.in'' von
``Autoscan''. Nach dem man Verbesserungen oder Erweiterungen in dieser
Datei vorgenommen hat, kann man sie in ``configure.in'' umbenennen.

Die hier folgende ``configure.in'' wurde mit \texttt{autoscan} erstellt,
worauf hin einige Punkte von Hand hinzugef\"ugt wurden.

\begin{verbatim}
AC_PREREQ(2.59)
AC_INIT([hello],[1.0],[peternov1@gmx.de])
AM_INIT_AUTOMAKE([hello],[1.0])

AC_ARG_ENABLE([repeat],
  AS_HELP_STRING([--enable-repeat],
    [Repeat the output of 10 times]),
  [if test "x$enableval" = "xyes" ; then
    AC_DEFINE(CONFIG_REPEAT,,
      [Repeat the output of the programm 10 times.])
  fi])

AC_CONFIG_SRCDIR([hello.c])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_FILES([Makefile])

AC_PROG_CC
AC_OUTPUT
\end{verbatim}

Das erste Makro AC\_PREREQ, mit ``2.59'' als Argument, stellt sicher, dass
eine gleiche oder h\"ohere Version von \textit{Autoconf} benutzt wird, um
``configure'' zu erstellen. Ist auf dem System eine niedriegere Version
installiert, wird sich \textit{Autoconf} mit einer Warnung beenden.  Somit
kann man sicherstellen, dass kein, aus Versionsgr\"unden, falsches
``configure'' erstellt wird. AC\_PREREQ ist das einzige Makro, welches vor dem
AC\_INIT vorkommen darf.

AC\_INIT ist das \textit{Autoconf}-Initialisierungsmakro. Es ist das Makro,
welches, mit der Ausnahme von AC\_PREREQ, als erstes in der ``configure.in''
vorkommen muss. Es nimmt drei Parameter entgegen: Den Projektnamen, die
Projektversion und die E-Mail Addresse, an welche ``Bugreports'' geschickt
werden sollen. Hier sieht man, dass alle Parameter mit den eckigen Klammern
umgeben sind. Dies ist das ``Quoten''.

Nachdem auch \textit{Automake} die ``configure.in'' w\"ahrend seinem Ablauf
ananlysiert, ist es notwendig das AM\_INIT\_AUTOMAKE Makro darin zu plazieren;
am besten gleich nach der \textit{Autoconf}-Initialisierung. Die beiden
Parameter sind wie zuvor der Projektname und die Projektversion.

Mit dem Makro AC\_CONFIG\_SRCDIR \"uberpr\"uft \textit{Autoconf}, ob das
richtige Verzeichnis f\"ur den Quellcode angegeben wurde, da es zum Zeitpunkt
des Aufrufs von ``configure''  m\"oglich ist, das Quellverzeichnis explizit
anzugeben. Dem Makro wird eine Datei \"ubergeben, so dass \textit{Autoconf}
feststellen kann, ob sich diese Datei in dem Ordner befindet. Kann sie nicht
gefunden werden, ist offensichtlich das falsche Verzeichnis angegeben worden.

Das Makro AC\_CONFIG\_FILES, mit dem Argument ``Makefile'', weist
\textit{Autoconf} an, nach einer Datei names ``Makefile.in'' zu suchen, alle
Variablen dort mit den entsprechenden Werten zu ersetzten und die Ausgabe in
``Makefile'' zu speichern.

Das AC\_PROG\_CC f\"uhrt mehr oder weniger Checks im System durch, um
sicherzustellen, dass ein funktionierender C Compiler vorhanden ist und setzt
Umgebungsvariablen, damit Ersetzungen in der ``Makefile.in''
vorgenommen werden k\"onnen.

Das letzte Makro hei"st AC\_OUTPUT. Dieses bildet immer den Abschlu"s einer
``configure.in''. Dieses Makro ist neben AC\_INIT das einzige, welches
definiert sein muss.

Neben den bereits besprochenen Makros, ist unter anderem noch AC\_ARG\_ENABLE
von Hand eingef\"ugt worden. Dieses Makro ist daf\"ur verantwortlich, dass das
Konfigurationsskript bspw. die \texttt{--enable-repeat} Option versteht.
Obwohl das Makro ziehmlich kompliziert aussieht, besteht es im Grunde genommen
nur aus drei Argumenten. Das erste \"ubergebene Argument ist der Name der
Option.  Als zweites kommt, ein Hilfetext, der bei dem einem Aufruf von
``configure'' mit der Option \texttt{--help} ausgegeben wird. Als drittes
bekommt das Makro einen Shell-code, der dann ausgef\"uhrt wird, wenn die
Option (hier \texttt{--enable-repeat}) beim Konfigurieren angegeben wurde. In
diesem Fall wird eine interne Shellvariable auf einen Wert gesetzt, der ohne
Argumente an die Option ``yes'' ist (siehe
\texttt{--enable-\textit{feature=[arg]}} auf Seite
\pageref{ref:enable-feature}). Wird das Feature beim Konfigurieren
ausgew\"ahlt, so wird \textit{Autoconf} angewiesen die Pr\"aprozessorvariable
CONFIG\_REPEAT zu definieren. Dies geschieht \"uber das Makro AC\_DEFINE.

Last but not least ... Im Absatz zuvor wurde eine Pr\"aprozessorvariable
definiert. Die Frage ist jedoch: Wo wird sie definiert?  Wie wird sie dem
Quelltext bekannt gemacht? Prinzipiell ist es m\"oglich solche Variablen
\"uber die ``-D'' Option eines Compilers dem Quelltext bekannt zu geben.  Dies
kann jedoch zu Problemen f\"uhren. Deshalb wird eine Datei names ``config.h''
erstellt, die die Definitionen wie z.B. CONFIG\_REPEAT enth\"alt. Die
``config.h'' inkludiert der Quelltext im hiesigen Beispiel. Das Makro
AC\_CONFIG\_HEADER l\"a"st die Definitionen in die Datei ``config.h''
einflie"sen, vorausgesetzt die entsprechende Datei ``config.h.in'' existiert.

\subsection{config.h.in}
``config.h.in'' ist ein Template f\"ur die durch ``configure'' zu entstehende
``config.h''. Wie \textit{Autoscan} f\"ur ``configure.in'', so ist
\textit{Autoheader} f\"ur die Erstellung von ``config.h.in'' ein Werkzeug, das
die gesamte Operation automatisiert. \texttt{autoheader} scant die zuvor
erstellte ``configure.in'' nach Definitionen f\"ur den Pr\"aprozessor und
erstellt eine entsprechende ``config.h.in''.


\subsection{Erstellen des Pakets}
Nun sind alle erforderlichen Dateien (siehe Abschnitt Files auf Seite
\pageref{sec:Files}) erstellt und man kann das ``configure'' erstellen.
Das Kommando \texttt{ls} sollte die folgenden Ausgabe produzieren:

\begin{verbatim}
$ pwd
/home/pete/hello
$ ls -F
AUTHORS    Makefile.am  README       configure.in
ChangeLog  NEWS         config.h.in  hello.c
\end{verbatim}

Die letzten Schritte zu einem eigenen Softwarepaket ``Hello 1.0'' sind nur noch
eine Kleinigkeit.

\begin{enumerate}
\item Es ist notwendig das Tool \texttt{aclocal} aufzurufen.
  Dieses f\"uhrt einige wichtige Schritte durch, um sicherzustellen, dass die
  in ``configure.in'' verwendeten Makros richtig umgesetzt werden.
  
\item Nun kann \texttt{autoconf} aufgerufen werden. Sollten sich Fehler in der
  Eingabedatei ``configure.in'' befinden, wird \textit{Autoconf} dies melden
  und die Arbeit abbrechen. Nach dem erfolgreichen Ablauf des Programms sollte
  im Verzeichnis das lang ersehnte Skript ``configure'' liegen.

\item ``configure'' kann jedoch noch nicht erfolgreich
  aufgerufen werden, da immer noch die ``Makefile.in'' fehlt. Diese wird
  einfach mit \texttt{automake} aus der Eingabedatei ``Makefile.am''
  erstellt. In hiesigen Beispiel wird sich \textit{Automake} dar\"uber
  beklagen, dass immer noch einige Dateien fehlen. Diese kann
  \textit{Automake} automatisch anlegen, in dem man dem Tool die Option
  \texttt{--add-missing} auf den Weg gibt.
\end{enumerate}

Jetzt sollte das Projektverzeichnis wie folgt aussehen:
\begin{verbatim}
$ pwd
/home/pete/hello
$ ls -F
AUTHORS      Makefile.in      config.h.in   install-sh@
COPYING@     NEWS             configure*    missing@
ChangeLog    README           configure.in
INSTALL@     aclocal.m4       depcomp@
Makefile.am  autom4te.cache/  hello.c
\end{verbatim}

Voil\`{a} ... es liegt ein Projekt nach allen Regel der Kunst im Zeichen des
GNUs\footnote{Die Anspielung hier meint das GNU Projekt von Richard M.
  Stallman, der mit anderen Programmierern die GNU Coding Standards entworfen
  hat.} vor. Allerdings ist mit all diesen Schritten nicht sichergestellt, dass
es Fehler nicht gibt. Das Testen und Verbessern bleibt nicht aus.

Da nun ein ``configure'' und die ``Makefile.in'' vorliegen, kann die Software
erstellt werden. Das Paket kann mit \texttt{./configure [options]}
konfiguriert werden. Das Skript nimmt nun die als Kommandozeilenparameter
\"ubergebenen Optionen entgegen und erstellt zusammen mit den aus der Umgebung
ermittelten Systemeigenschaften eine ``Makefile'' an Hand der Vorlage aus
``Makefile.in''.

Wie versprochen, sollte nun die Software mit einem einfachen
\textit{./configure \&\& make \&\& make install} zu erstellen und zu
installieren sein. Wird dem ``configure'' in vorliegenden Beispiel die Option
\texttt{--enable-repeat} mit auf den Weg gegeben, sollte das erstellte
Programm zehn mal den String ``Hello World!'' ausgeben.

\subsection{Das Paket erstellen}
Beim Erstellen eines Sourcecodepakets stellt sich grunds\"atzlich die Frage:
Welche Dateien geh\"oren in das resultierende ``tar.gz'' Archiv? Hier spaltet
sich die Meinung der Experten stark. W\"ahrend auf der einen Seite die Theorie
steht, dass man nur die von Hand erstellten Dateien in die Archive packen
sollte, ist es doch sehr \"ublich die Pakete schon mit dem fertigen
``configure'' und der ``Makefile.in'' auszuliefern.
Die letztere Methode, Pakete, die an Normaluser
gehen, mit dem generierten ``configure'' zu erstellen, hat sich
stark verbreitet, so dass der Benutzer nur noch \textit{./configure \&\& make
  \&\& make install} ausf\"uhren muss und \textit{Autoconf} wie
\textit{Automake} nicht zu installieren braucht. Werden die Dateien dagegen
z.B. f\"ur ein Backup oder in einem CVS-Repository abgelegt, sollten sich dort
keine automatisch generierbaren Files befinden.

Um nun ein fertiges, benutzerfreundliches Softwarepaket im Sourcecodeformat zu
erstellen, packt man es am besten in ein ``zipped tape archive'' mit der
\"ublichen Endung ``tar.gz''. Der Name des Archivs sollte in vorliegenden
Beispiel ``hello-1.0.tar.gz'' lauten, wobei das Verzeichnis nach dem entpacken
auch ``hello-1.0'' lauten sollte. Auf solche Kleinigkeiten und weitere Details
jedes mal von Hand zu achten macht keinen Sinn und ist sehr fehleranf\"allig.
Deshalb braucht man auch hierf\"ur eine automatisierte Methode. Was leicht zu
\"ubersehen ist, ist die Tatsache, dass \textit{Automake} in der generierten
``Makefile.in'' ein Target mit dem Namen ``dist'' reserviert, welches das
Erstellen des Archivs \"ubernimmt. Ein einfaches
\texttt{make~dist}\footnote{``dist'' steht f\"ur ``distribution''} erstellt
das gew\"unschte Paketarchiv und legt es im Projektverzeichnis ab.  Dieses
kann man nun auf die Projektseite zum Download anbieten oder auf einen
FTP-Server stellen oder direkt an seine Freunde verschicken. Man darf jedoch
nicht vergessen, dass das \texttt{make} Kommando eine ``Makefile'' braucht,
also muss man zuvor ``configure'' ausf\"uhren, so lange keine ``Makefile'' im
Projektordner vorhanden ist.
