Benutzung von Autoconf

Einführung

Autoconf ist ein Tool das Shell-Skripte erzeugt, die dann automatisch Software-Quellcode-Pakete konfigurieren, um sie an Unix-ähnliche Systeme anzupassen.
Die von Autoconf erzeugten Konfigurationsskripte sind unabhängig von Autoconf, so das der Benutzer Autoconf nicht installiert haben muss.

Features

Die Autoconf-Skripte benötigen keine Benutzerinteraktion, wenn sie einmal laufen. Selbst Parameter müssen selten angegeben werden. Sie testen das System selbstständig nach den vorhandenen Funktionen die das Softwarepaket benötigt oder optional verwendet. Vor jedem Test wird eine einzeilige Meldung ausgegeben, die dem Benutzer mitteilt, was gerade getestet wird. Autoconf kann mit verschieden Unix-Varianten umgehen, ohne das irgendwelche Listen von Funktionen für jede Version von Unix-Derivaten geführt werden müssen.

Verwandte Tools

Tools die mit Autoconf verwandt sind, bzw. eine ähnliche Funktionalität erfüllen sind Metaconfig und imake.

Benutzung

Die Benutzung gestaltet sich im Regelfall als sehr einfach.
Man entpackt das Quellcode-Archiv
tar xzvf MeinPacket.tar.gz
wechselt in das erstellte Verzeichnis
cd MeinPacket
liest sich evtl. vorhandene Installations-Dokumentation durch.
Und gibt dann meistens einfach
./configure && make && make install
ein.

Parameter

Parameter die man dem Autoconf-Skript geben kann, erfährt man mit
./configure --help
Die Ausgabe sieht bei z.B. Mico (www.mico.org) so aus:
1stpc:/opt/soft/mico # ./configure --help
Usage: configure [options] [host]
Options: [defaults in brackets after descriptions]
Configuration:
  --cache-file=FILE       cache test results in FILE
  --help                  print this message
  --no-create             do not create output files
  --quiet, --silent       do not print `checking...' messages
  --version               print the version of autoconf that created configure
Directory and file names:
  --prefix=PREFIX         install architecture-independent files in PREFIX
                          [/usr/local]
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                          [same as prefix]
  --bindir=DIR            user executables in DIR [EPREFIX/bin]
  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
  --datadir=DIR           read-only architecture-independent data in DIR
                          [PREFIX/share]
  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
                          [PREFIX/com]
  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
  --includedir=DIR        C header files in DIR [PREFIX/include]
  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
  --infodir=DIR           info documentation in DIR [PREFIX/info]
  --mandir=DIR            man documentation in DIR [PREFIX/man]
  --srcdir=DIR            find the sources in DIR [configure dir or ..]
  --program-prefix=PREFIX prepend PREFIX to installed program names
  --program-suffix=SUFFIX append SUFFIX to installed program names
  --program-transform-name=PROGRAM
                          run sed PROGRAM on installed program names
Host type:
  --build=BUILD           configure for building on BUILD [BUILD=HOST]
  --host=HOST             configure for HOST [guessed]
  --target=TARGET         configure for TARGET [TARGET=HOST]
Features and packages:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --x-includes=DIR        X include files are in DIR
  --x-libraries=DIR       X library files are in DIR
--enable and --with options recognized:
  --enable-corba2-1,      makes MICO 2.1 conformant
  --disable-coss,         do not use MICO COSS
  --disable-naming,       do not use MICO Naming Service
  --disable-relship,      do not use MICO Relationship Service
  --disable-events,       do not use MICO Event Service
  --disable-streams,      do not use MICO Stream Service
  --disable-property,     do not use MICO Property Service
  --disable-trader,       do not use MICO Trading Service
  --disable-mini-stl      do not use MICO-supplied STL
  --enable-repo           use gcc's template repository
  --disable-optimize      do not use -O to compile
  --enable-debug          use -g to compile
  --disable-shared        don't build shared libs
  --disable-static        don't build static libs
  --disable-dynamic       disable dynamic loading
  --enable-final          build size optimized lib (needs lots of memory)
  --disable-except        disable exception handling
  --disable-std-eh        disable CORBA compliant exception handling
  --enable-cd             disable use of fancy libs etc
  --with-qt=qtdir         use QT installed in qtdir
  --with-gtk=gtkdir       use GTK installed in gtkdir
  --with-tcl=tcldir       use TCL installed in tcldir
  --with-ssl=ssldir       use SSLeay installed in ssldir
  --disable-split         dont split large source files
  --disable-namespace     do not use namespaces
  --disble-orb-excepts    built libmico without exception support
  --enable-memcheck       for debugging MICO memory management
  --enable-compiled-headers  use precompiled headers if supported
  --enable-speed-tune  compile MICO for maximum peformance
  --with-gtk-prefix=PFX   Prefix where GTK is installed (optional)
  --with-gtk-exec-prefix=PFX Exec prefix where GTK is installed (optional)
  --disable-gtktest       Do not try to compile and run a test GTK program
  --with-x                use the X Window System

Normalerweise gestaltet sich die Ausgabe aber wesentlich kürzer ;-)
Interessant für den Benutzer sind folgende allgemeine Optionen:
--prefix=PREFIX         install architecture-independent files in PREFIX
                        [/usr/local]
Hiermit wird bestimmt in welches Verzeichnis das Program installiert werden soll. Die Standardeinstellung ist /usr/local . z.B. mit
./configure --prefix=/opt/mico
wir Mico nach /opt/mico installiert.
Man sollte allerdings beachten, das andere Pakete die z.B. Mico benötigen ihn in /usr oder /usr/local erwarten. Sie müssten nun deren Autoconf-Scripten irgendwie sagen das Mico in /opt/mico installiert ist, wenn es deren Script erlaubt. Deshalb ist ist Standardeinstellung /usr/local immer eine gute Wahl.
Um z.B. dem Mico-Script zu sagen, wo die Qt-Bibliothek installiert ist, kann man --with-qt verwenden. Also z.B.
./configure --prefix=/opt/mico --with-qt=/opt/qt-1.44
Wenn man bestimmte Funktionen vom Paket ein- oder ausschalten möchte, benutzt man die --enable-FEATURE oder --disable-FEATURE Parameter. z.B.
./configure --enable-shared --disable-static
veranlasst das nur dynamische und keine statischen Bibliotheken erstellt werden.
Wenn man bestimmen will daß das Paket bestimmte andere installierte Pakete verwenden soll, benutzt man die --with-PACKAGE und --without-PACKAGE Parameter. z.B. wird Mico mit folgendem Kommando ohne Benutzung von X11 kompiliert.
./configure --without-x

Umgebungsvariablen

Wenn man will, daß das Quell-Paket z.B. mit bestimmten Compiler-Flags kompiliert werden sollen, kann man dies durch setzen von Umgebungsvariablen erreichen. Autoconf-Skripte beachten unter anderem folg. Umgebungsvariablen:
CCZu verwendender C-Compiler
CXXZu verwendender C++-Compiler
CFLAGSDebug- und Optimierungsoptionen für den C-Compiler
CPPFLAGSInclude-Verzeichnisse und andere versch. C-Compileroptionen
CXXFLAGSDebug- und Optimierungsoptionen für den C++-Compiler
DEFS-D Optionen für den C-Compiler (z.B. -DLINUX)
LDFLAGSOptionen für den Linker (z.B. -s für automatisches Stripping)
LIBS-l und -L Optionen für den Linker

Häufige Probleme und Fehlerbeseitigung

Grundsätzlich sollten bei der Benutzung von Autoconf-Scripten keine Probleme auftreten. Bei der häufigen Installation von Quellcodepaketen trifft man aber immer wieder auf die gleichen kleinen Probleme, die sich meist leicht beheben lassen. Hierzu ist allerdings ein Verständis von der Zusammenhänge nötig.
Grund für diese Probleme sind zum einen falsch installierte Pakete als auch schlechte selbstgeschriebene Tests der Entwickler. Also meldet das Autoconf-Script das irgendein Paket nicht installiert sei, obwohl dies der Fall ist, und bricht ab.

Caching der Tests

Beim erstmaligen Starten von configure ist die erste Meldung
creating cache ./config.cache
Hier wird die Datei config.cache angelegt, in der die Ergebnisse der Tests gecached werden. Ob ein Test gecached ist gibt configure für jeden Test aus.
checking for sys/time.h... (cached) yes
Wenn z.B. ein Entwickler vergisst vor dem Release seine config.cache zu löschen, ist es möglich das bei Ihnen die gecachten Einträge des Entwicklers geladen werden. Dies kann dann dazu führen das sich das Paket nicht kompilieren lässt.

Fehlerfindung

Bei jedem Start von configure wird eine Datei namens config.log erstellt. In diese Datei wird die Zeilenummer des Tests in configure, das ausgeführte Kommando und bei Fehlern die Fehlerausgabe geschrieben. Hier lässt sich also der Grund des Fehlers finden. Wenn man z.B. die folgende Ausgabe erhält
checking for Qt... configure: error: Qt >= 1.42 (headers and libraries) not found.
Please check your installation!
liefert einem der Blick in config.log
....
configure:3332: checking for Qt
tried /usr/lib/qt/lib
tried /usr/X11R6/lib
tried /usr/lib
tried /usr/local/qt/lib
tried /usr/lib/qt
tried /usr/X11R6/lib
configure:3437: c++ -o conftest -O2 -Wall -INO    -LNONE  -L/usr/X11R6/lib conftest.C  -lqt -lXext -lX11  1>&5
conftest.C:2: qglobal.h: No such file or directory
conftest.C:3: qapplication.h: No such file or directory
conftest.C:4: qobjcoll.h: No such file or directory
conftest.C:7: #error 1
configure: failed program was:
#include "confdefs.h"
#include 
#include 
#include 

#if ! (QT_VERSION >= 142)
#error 1
#endif

int main() {
    return 0;
}
Ein erfahrener User/Entwickler erkennt sofort, das der gcc die Header-Files von Qt nicht finden kann. Also setzt man z.B. die Umgebungsvariable CPPFLAGS auf das include-Verzeichnis von Qt:
export CPPFLAGS=-I/opt/qt-1.42/include
Wir erhalten beim erneuten Start von configure wieder dieselbe Fehlermeldung. Der Inhalt der Datei config.log ist diesmal aber anders.
configure:3332: checking for Qt
tried /usr/lib/qt/lib
tried /usr/X11R6/lib
tried /usr/lib
tried /usr/local/qt/lib
tried /usr/lib/qt
tried /usr/X11R6/lib
configure:3437: c++ -o conftest -O2 -Wall -INO   -I/opt/qt-1.42/include -LNONE
-L/usr/X11R6/lib conftest.C  -lqt -lXext -lX11  1>&5
/usr/bin/ld: cannot open -lqt: No such file or directory
collect2: ld returned 1 exit status
configure: failed program was:
#include "confdefs.h"
#include 
#include 
#include 

#if ! (QT_VERSION >= 142)
#error 1
#endif

int main() {
    return 0;
}
Diesmal findet der Linker die Qt-Library nicht. Genauer genommen die Datei libqt.so, welche sich in /opt/qt-1.42/lib befindet. Auch hier wäre eine Lösung, das setzen der Umgebungsvariable LIBS
export LIBS=-L/opt/qt-1.42/lib
Nun sollte zumindest der Compileraufruf funktionieren. Einfacher wäre gewesen, wie in der Qt-Installationsdokumentation beschrieben, die Variable QTDIR auf /opt/qt-1.42 zu setzen, da der configure-Test diese zuerst beriücksichtigt.

vi configure

Wenn man das Script auch mit Kommandozeilenparametern und dem Setzen von Umgebungsvariablen nicht, überreden kann, das Testprogramm zu kompilieren, falls etwa die gcc-Parameter falsch sind, kann man den Test auch komplett aus dem Script entfernen. Die Datei config.log sagt einem, in welcher Zeile sich der Test befindet. Ein bißchen Erfahrung von Shellprogrammierung und Phantasie beim interpretieren des Script ist allerdings von nöten, genauso wie das nachträgliches Anpassen der Makefiles.

Eine zweite Möglichkeit wäre die Datei config.status zu verändern und danach auszuführen. Hierbei handelt es sich nur um ein von configure generiertes Script, welches die Makefiles konfiguriert. Dies sollte man im Anschluß an die Änderungen noch ausführen. Damit spart man sich das manuelle ändern der Makefiles, welches bei grö฿eren Projekten sehr aufwendig werden kann.

vi configure.in

Wenn Sie Erfahrung mit der Entwicklung von Autoconf Scripten haben, können Sie natürlich auch die meist mitgelieferte Quelldatei configure.in direkt ändern, und die Fehler so direkt beseitigen. Vorrausgesetzt Sie haben dieselbe oder eine kompatible Version von Autoconf.