18 Kompilieren und Optimieren
Im vorliegenden Kapitel zeige ich Ihnen, wie Sie einen »Software-Maßanzug« für Ihre aktuelle Hardware herstellen.
Würden Sie einen Porschemotor in einen Smart einbauen? Oder umgekehrt einen Porsche mit einem Smartmotor versehen? Genau dies geschieht im übertragenen Sinne bei der Verwendung gängiger Betriebssysteme. Die Entwickler versuchen stets, Diener vieler Herren zu sein, ohne dabei auf die Stärken und Schwächen der Hardware, auf der das System eingesetzt werden soll, einzugehen.
Linux besitzt die einzigartige Möglichkeit, voll konfigurierbar und skalierbar zu sein. Das System macht in der Armbanduhr als Embedded System eine ebenso gute Figur wie als Cluster-Betriebssystem des Rechnerparks einer Universität. Das Geheimnis besteht darin, dass das System quelloffen ist und daher (einen entsprechenden Compiler vorausgesetzt) auf viele Systeme portiert und an diese angepasst werden kann. Der folgende Abschnitt zeigt, wie man selbst eine optimale Anpassung der Software an den heimischen PC erreicht. Der Ubuntu-relevante Part stammt z. T. aus einigen lesenswerten Artikeln des Ubuntuusers-Wiki, dessen Autoren wir an dieser Stelle für die geleistete Arbeit danken.
18.1 Sekundärsoftware aus Quellen
Bei jedem Programm für Linux hat man die Möglichkeit, selbst Hand anzulegen und die Quellpakete selbst zu kompilieren und zu installieren. Dies funktioniert jedoch nicht immer auf Anhieb, da hierbei die Abhängigkeiten nicht automatisch aufgelöst werden. Die allermeisten Entwickler von Programmen stellen auf ihrer Homepage die Quellpakete der Programme zur Verfügung. Diese sind meist im tar.gz- oder einem anderen Format gepackt und müssen mit einem Packprogramm wie z. B. guitar oder Ark (KDE) entpackt werden.
18.1.1 Der Linux-Dreisprung
Um die entpackten Dateien weiter bearbeiten zu können, muss man der Besitzer sein oder Root-Rechte haben. Meist werden die Dateien nach dem Muster des folgenden Dreisprungs (dem Linux-Dreisprung) kompiliert und installiert (Abbildung 18.1).
Abbildung 18.1 Der »Linux-Dreisprung«
Zunächst wird über das Konfigurationsskript configure[Das vorangestellte Kürzel .] bedeutet, dass die Konfigurationsroutine aus dem aktuellen Verzeichnis aufgerufen wird. die eigentliche Kompilierumgebung angepasst und geprüft, ob sämtliche für den Übersetzungsprozess notwendigen Pakete auf dem System zur Verfügung stehen. Bei etwaigen Fehlermeldungen müssen dann meist die so genannten Developer-Pakete, welche die fehlenden Bibliotheken oder Header enthalten, nachinstalliert werden.
Beim Kompilieren über make wird der Quellcode des Programms in eine ausführbare Datei umgewandelt. Danach wird diese über
user$ sudo make install
installiert, d. h., sie wird in den Programmordner verschoben, mit anderen Dateien und Bibliotheken verknüpft und eventuell wird ein Eintrag im GNOME- bzw. KDE-Menü erstellt. Dazu sind meist Root-Rechte erforderlich, daher die Verbindung mit sudo.
Bei vielen Programmen liegt den gepackten Dateien eine Anleitung namens README oder INSTALL bei, die man unbedingt beachten sollte!
Die obige Vorgehensweise lässt sich bei nahezu allen Linuxdistributionen durchführen. Einen Schönheitsfehler gibt es hier dennoch: Das durch make install (mit Root-Rechten!) aufgerufene Skript packt die ausführbaren Dateien zumeist in Pfade, die nach der Installation nicht mehr so einfach nachvollziehbar sind. Möchte man die Software bei Nichtgefallen wieder entfernen, so weiß man zumeist nicht mehr, wo sich die einzelnen installierten Dateien befinden.
18.1.2 Reversible Installation
Anwenderfreundliche Programmierer haben für diesen Zweck meist das Target uninstall vorgesehen. Dieses setzt allerdings voraus, dass Sie das Entpack-und Arbeitsverzeichnis der Software noch nicht gelöscht haben. Wechseln Sie in dieses Verzeichnis und führen Sie zur Deinstallation folgenden Befehl aus:
user$ sudo make uninstall
Sollte der Programmierer kein uninstall vorgesehen haben, so gibt es zwei Möglichkeiten:
- Protokollieren Sie die bei der Installation durchgeführten Kopiervorgänge in einer Logdatei (z. B. softinst.log):
user$ sudo make install > softinst.log
- Verwenden Sie zur reversiblen Installation von Software das Paket checkinstall: Dieses Programm erzeugt ein rudimentäres Debian-Paket aus Ihren übersetzten Binärdateien, das mit dem gewöhnlichen Debian-Paketmanager ohne Spuren wieder entfernt werden kann.
18.1.3 Installation unter Ubuntu
Im Folgenden finden Sie eine kurze Übersicht darüber, was beim Kompilieren von Sekundärsoftware speziell unter Ubuntu-/Debian-Systemen zu beachten ist. Stellen Sie zunächst sicher, dass die folgenden Pakete auf Ihrem System installiert sind:
- build-essential
- checkinstall
Sämtliche der folgenden Schritte finden innerhalb einer Konsole statt. Zunächst besorgt man sich die Quelltext-Dateien des gewünschten Programms aus dem Internet.
Handelt es sich um ein Ubuntu-Standard/Universe/Multiverse-Paket, dann haben Sie es besonders einfach: Die Quellen können Sie sich auch aus dem Repository beschaffen, lesen Sie dazu einfach in Abschnitt 18.1.5 weiter. Im anderen Fall ist folgendermaßen zu verfahren:
Entpacken der Quellen
Die Quelltext-Dateien, die das Programm ausmachen, sind stets gepackt und komprimiert. Normalerweise werden dabei Verzeichnisse mit dem Archivierungsprogramm tar (vgl. die Referenz in Abschnitt 24) in einer Datei mit der Endung .tar zusammengefasst. Um Bandbreite zu sparen, werden diese tar-Archive dann auch noch mit gzip komprimiert, so dass letztlich Dateien der Form <progname>.tgz oder <progname>.tar.gz zur Verfügung stehen. Manchmal wird auch nicht mit gzip, sondern mit dem Programm bzip2 komprimiert. Das Archiv hat dann einen Namen der Form <progname>.tar.bz2.
Zunächst sollte man ein Verzeichnis anlegen, in dem das heruntergeladene Archiv gespeichert wird. Das kann z. B. der Ordner packages im Heimverzeichnis sein. Dort kann man das Archiv nach dem Download entpacken. Für Archive mit der Endung *.tgz oder *.tar.gz geht das folgendermaßen:
user$ tar -xzf Dateiname
Für Archive mit der Endung .tar.bz2 verwendet man:
user$ tar -xjf Dateiname
Beachten Sie, dass zum Entpacken und Kompilieren der Software noch keine Root-Rechte erforderlich sind.
Normalerweise entsteht beim Entpacken ein neues Verzeichnis mit dem Namen des Pakets, in das man nun wechselt:
user$ cd Verzeichnisname
Installationsanweisung lesen
Zugegeben, fast alle Installationen laufen nach dem gleichen Verfahren ab. Aber manchmal gibt es eben doch Abweichungen. Deshalb lohnt es sich, in Dateien wie INSTALL und README nach Hinweisen auf benötigte Programme bzw. Bibliotheken oder mögliche Probleme samt Lösungen zu suchen. Auch eventuell abweichende Installationsverfahren sind hier erklärt. Diese Dateien können bequem mit einem Editor Ihrer Wahl gelesen werden, notfalls tut es auch der Pager less auf der Kommandozeile.
Konfigurieren
Der folgende Befehl startet die Erstellung einer Konfiguration, die später zur eigentlichen Übersetzung des Quellcodes und zur Installation benötigt wird:
user$ ./configure --prefix=/usr/local
Das geänderte Präfix trägt der speziellen Ubuntu-Verzeichnisstruktur Rechnung, in den meisten Fällen können Sie aber das Präfix auf der Voreinstellung belassen. Optionale Features des Programms kann man mit Optionen wie ---enable-xyz ein- und mit ---disable-xyz ausschalten. Die vollständige Auflistung aller möglichen Optionen bringt
user$ ./configure --help
Wenn man Glück hat, läuft der Konfigurationsprozess ohne Fehlermeldungen durch. Meist endet die Ausgabe mit einer ausdrücklichen Erfolgsmeldung und der Aufforderung, jetzt make zu starten.
Was tun bei Fehlern?
Mit weniger Glück fehlt die eine oder andere Komponente, und man bekommt eine Fehlermeldung, die z. B. so aussehen kann:
checking for XML::Parser... configure: error: XML::Parser perl module is required for intltool
Was kann man mit dieser Meldung anfangen? Alle benötigten Informationen stecken in der Fehlermeldung: Es wird etwas benötigt, das mit »xml«, »parser« und »perl« zu tun hat. Also sucht man nach einem Paket, das all diese Bestandteile im Namen enthält. Dazu verwendet man das Tool aptitude:
user$ aptitude search ~nxml~nparser~nperl p libxml-parser-perl - Perl module for parsing XML files
~n leitet dabei ein Wort ein, das als Teil eines Paketnamens gesucht werden soll.
Hilft das noch nicht? Dann könnte ~d helfen, dieser Parameter durchsucht statt des Paketnamens gleich den gesamten Beschreibungstext. In diesem Fall war der erste Befehl allerdings schon erfolgreich: er führte zum Paket libxml-parser-perl. Installieren Sie das benötigte Paket über
user$ sudo apt-get install libxml-parser-perl
und starten Sie die Konfiguration erneut.
Benötigte Pakete beginnen meist mit lib. Stehen mehrere Pakete zur Auswahl, dann ist dasjenige richtig, das auf -dev endet.
Übersetzen
Der nächste Schritt ist meist einfach:
user$ make
Währenddessen kann man je nach Programmgröße und Rechenleistung eine Tasse Kaffee holen und/oder an etwas anderem arbeiten.
Was tun bei Fehlern?
Auch bei make kann im Prinzip mal etwas schiefgehen. Der erste Schritt ist wieder die Untersuchung der Ausgabe. Dabei kommt es diesmal nicht auf die letzten Zeilen an, die meist nur Folgefehler enthalten, sondern auf eine Zeile, die, wenn man Glück hat, auf eine fehlende Datei mit der Endung .h verweist. Hat man diese Datei gefunden, ist das Problem schon so gut wie gelöst, und der größte Aufwand ist die Erstellung einer Fehlermeldung an den Programmautor wegen eines unvollständigen configure-Skriptes, das die fehlende Komponente nicht bemerkte.
Wir müssen nun herausbekommen, welches Paket die fehlende Datei enthält. Dazu muss das Paket apt-file aus dem Universe-Repository installiert sein. Die folgende Befehlsfolge aktualisiert zunächst die Datenbank von apt-file:
user$ sudo apt-file update
Da Sie auf das Debian-Paketsystem zugreifen, sind hierzu root-Rechte erforderlich (sudo). Nun können Sie nach der fehlenden Datei suchen:
user$ sudo apt-file search Dateiname
Das fehlende Paket ist nun zu installieren, danach kann make erneut gestartet werden. Glücklicherweise arbeitet es beim letzten Arbeitsstand weiter und fängt nicht wie configure ganz von vorne an.
Installieren
Der folgende Befehl startet die Verwandlung des Programms in ein simples .deb-Paket und startet dessen Installation:
user$ sudo checkinstall
Dabei werden einige Fragen gestellt, die man meist mit der Eingabe-Taste bestätigen kann.
Schlägt die Installation fehl, finden sich Informationen in der Ausgabe von dpkg, die man sich anzeigen lassen sollte. Wird dabei gemeldet, dass Dateien aus anderen Paketen überschrieben werden müssten, sollte man dies sehr gründlich abwägen. Eine Installation ließe sich in solchen Fällen zwar mit
user$ sudo dpkg --force-overwrite -i Paketname
erzwingen, von dieser Vorgehensweise ist jedoch abzuraten, da man dadurch meist ein inkonsistentes System riskiert.
Abweichende Installationsverfahren
Manche Programme verzichten auf ein configure-Script und werden nur mit make gebaut, andere verwenden ganz andere Systeme wie SCONS. Für all diese Verfahren gilt: Die eigentliche Installation sollte man durch Einsatz von checkinstall abfangen, da nur so das Paketsystem über die neuen Programme Bescheid weiß und das ungewollte Überschreiben von Dateien verhindert werden kann. Vor dem eigentlichen Installationsbefehl muss daher checkinstall eingefügt werden – aus sudo ./install.sh oder sudo scons install wird
user$ sudo checkinstall ./install.sh
oder
user$ sudo checkinstall scons install
In den meisten Installationsanleitungen, die nicht für Ubuntu geschrieben sind, fehlt sudo oder ist durch su ersetzt. Bei Ubuntu muss stets sudo verwendet werden.
18.1.4 Alternativen: dh_make und fakeroot
Als Alternative zu checkinstall und dem Vorspiel mit configure und make bieten sich die Kompilierung mittels dh_make und die Erstellung des Paketes über fakeroot an. Der Vorteil ist, dass weniger Befehle ausgeführt werden müssen, und dass fakeroot das *.deb-Paket ohne Nachfrage erstellt. Zusätzlich müssen hierfür die folgenden Pakete installiert sein:
- dh-make
- fakeroot
Die Schritte sind bis zu der Stelle, an der ./configure auszuführen ist, dieselben. Entpacken Sie also das Quelltext-Archiv und wechseln Sie in das entpackte Verzeichnis.
Anstatt ./configure führt man nun aber
user$ dh_make
aus. Die Frage nach dem Pakettyp bitte immer mit »Single Binary«, also »s« beantworten. Dies erstellt die Regeln für fakeroot, führt das configure-Skript aus und erzeugt eine Sicherheitskopie des Ordners mit dem Quelltext. Anschließend wird das Programm mit
user$ fakeroot debian/rules binary
kompiliert und sofort danach das .deb-Paket im Unterordner erstellt. Dieses lässt sich dann wie gewohnt mit dpkg installieren, wozu wieder Root-Rechte benötigt werden.
KDE-Programme kompilieren
Für sämtliche KDE Programme gilt, dass bei configure das Präfix auf /usr festgelegt werden muss:
user$ ./configure --prefix=/usr
18.1.5 Zwei Beispiele zur Installation
Ein einfaches Beispiel
Das folgende Beispiel zeigt die Kompilierung und Installation des klassischen Videoplayers MPlayer aus Quellen.
1. | 1. Laden Sie von der Seite des Projekts MPlayer (http://www.mplayerhq. hu) eine aktuelle Version des Programms herunter und entpacken Sie diese wie folgt in Ihrem Heimverzeichnis: |
user$ tar -xjf MPlayer-<Version>.tar.bz2
2. | 2. Begeben Sie sich nun in das entpackte Quellverzeichnis, bereiten Sie die Quellen vor und kompilieren Sie diese: |
user$ cd MPlayer-<Version> user$ ./configure Detected operating system: Linux Detected host architecture: i386 Checking for cc version ... 4.0.2, bad Checking for gcc version ... 4.0.2, bad Checking for gcc-3.4 version ... 3.4.5, ok Checking for host cc ... gcc-3.4 … user$ make
-
- Im vorliegenden Fall wurde übrigens der bei Ubuntu als Standard installierte C-Compiler gcc-4 als schlecht eingestuft, auf dem vorliegenden System ist allerdings noch parallel der gcc-3.4 installiert, mit dem sich die Software problemlos installieren lässt.
3. | 3. Bevor die Software installiert wird, empfiehlt es sich, diese zunächst lokal (d. h. in dem Verzeichnis, indem sie kompiliert wurde), zu testen. |
user$ ./mplayer <Testfilm>
4. | 4. Verläuft der Test erfolgreich, so kann das Programm schließlich installiert werden per sudo checkinstall |
Die Verwendung von checkinstall bei der MPlayer-Installation ist eigentlich nicht notwendig: Freundlicherweise stellen die Maintainer der Software dem Anwender die Möglichkeit zur Verfügung, die Software bei Nichtgefallen per make uninstall zu deinstallieren. Mehr noch: In einem Unterordner debian finden Sie einige Informationen darüber, wie sich leicht ein Debian-Paket erstellen lässt.
Ein komplexes Beispiel
Schwieriger wird die Kompilierung, wenn das Quellpaket auf anderen Paketen aufbaut und insbesondere so genannte Header-Dateien benötigt. Ein prominentes Beispiel findet man mit dem beliebten Videoumwandlungsprogramm transcode. Gerade wenn es um die Umwandlung von Videomaterial geht, macht sich eine perfekte Optimierung der Software bemerkbar.
Sie finden den Quellcode von transcode unter http://www.transcoding.org. Natürlich gibt es auch ein fertiges Debian-Paket, das mittels apt-get install transcode in kürzester Zeit auf Ihren Rechner befördert werden kann. Hierzu muss das Nerim/Marillat-Repository freigeschaltet werden. Dieses Binärpaket ist allerdings nur wenig optimiert.
Gehen Sie zum Kompilieren von transcode folgendermaßen vor:
1. | 1. Entpacken Sie zunächst die Quellen mittels |
user$ tar xvfz transcode-<Version>.tar.gz
2. | 2. Wechseln Sie nun in das Quellverzeichnis und versuchen Sie, die Quellen mit einigen komplexen Optionen zu konfigurieren[Im Normalfall wird man zunächst einmal versuchen, das Paket ohne Sonderoptionen zu kompilieren, die beschriebene Vorgehensweise dient ausschließlich Demonstrationszwecken.] (mehr zu diesen Optionen erfahren Sie über ./configure ---help): |
user$ cd transcode-<Version> user$ ./configure --prefix=/usr/local \ --enable-avifile --enable-ogg --enable-libdv \ --enable-mjpegtools --enable-a52
-
- Nun sollten Sie mit einigen Fehlermeldungen erschlagen werden, die darauf beruhen, dass etliche dev-Dateien (also im Wesentlichen Header) für die vorgewählten Optionen nicht zur Verfügung stehen:
… ERROR: option '--enable-mjpegtools' failed: cannot compile mjpegtools/yuv4mpeg.h mjpegtools/yuv4mpeg.h can be found in the following packages: mjpegtools http://mjpeg.sourceforge.net/ …
-
- Die obige Meldung resultiert also aus der Option ---enable-mjpeg tools. Sie können nun entweder auf die Option verzichten oder die fehlende Headerdatei ausfindig machen. Wir wählen letzteren Weg.
3. | 3. Wir verwenden das Werkzeug apt-file, um das zur fehlenden Dateigehörende Paket zu finden: |
user$ apt-file search yuv4mpeg.h libmjpegtools-dev:usr/include/mjpegtools/yuv4mpeg.h …
-
- Die Datei befindet sich also im Paket libmjpegtools-dev, das sogleich nachinstalliert werden soll:
user$ sudo apt-get install libmjpegtools-dev
4. | 4. Danach wird die Konfigurationsroutine zumindest nicht mehr an der Prüfung der MJPEG-Header scheitern. Auf diese Weise installieren Sie sämtliche benötigten Header, bis die Konfiguration glatt durchläuft. |
5. | 5. Schließlich ist das Programm mittels make und checkinstall zu kompilieren und zu installieren. |
Leider kann es wie oben bereits erwähnt auch vorkommen, dass der Kompiliervorgang mit make in Folge eines Fehlers im Konfigurationsskript stecken bleibt. Auch in diesem Fall ist zu 99\% eine fehlende Headerdatei der Übeltäter, es ist also mitunter Detektivarbeit angesagt, um derart komplexe Programme zu kompilieren.
Der einfache Weg
Sicher werden Sie sich fragen, ob die Sache mit dem Kompilieren von Programmen aus Quellen nicht auch einfacher zu realisieren ist. Dazu muss man ein klein wenig tiefer ins System eindringen. Zu fast jedem Ubuntu-Paket findet man stets ein gleichnamiges Quellpaket, vorausgesetzt, diese so genannten Sourcen werden in der Datei /etc/apt/sources.list durch das Schlüsselwort deb-src definiert. Im Falle der Ubuntu-Standard/Universe/Multiverse-Pakete muss man lediglich das Kommentarzeichen »#« vor den Quellverzeichnissen löschen, um diese zu aktivieren.
# Auszug aus /etc/apt/sources.list # Binärpakete deb http://de.archive.ubuntu.com/ubuntu breezy universe multiverse main restricted # Quellpakete deb-src http://de.archive.ubuntu.com/ubuntu breezy universe multiverse main restricted
Die Auswahl der Sourcen lässt sich natürlich auch einfach über Synaptic erledigen. Um nun für unser spezielles Beispiel transcode die Quellen freizuschalten, ist folgender Eintrag in der Datei sources.list vorzunehmen:
## Videorepository Marillat deb ftp://ftp.nerim.net/debian-marillat/ sarge main deb-src ftp://ftp.nerim.net/debian-marillat/ sarge main
Danach ist wie üblich ein sudo apt-get update vorzunehmen. Möchte man nun die Quellen eines Pakets wie z. B. transcode auf den Rechner befördern, so muss der folgende Befehl verwendet werden:
user$ sudo apt-get source <Paketname>
Die Quellen landen dabei im aktuellen Verzeichnis. Sollen diese gleich nach dem Herunterladen kompiliert werden, so ergänzt man den Befehl um den Parameter -b. Da bei einer derart komplexen Software wie transcode aber mit Sicherheit einige unaufgelöste Abhängigkeiten auftreten, verwendet man stattdessen den folgenden Befehl:
user$ sudo apt-get build-dep transcode
In diesem Fall werden sämtliche Programme und Bibliotheken, die für eine erfolgreiche Kompilierung des Programms erforderlich sind, auf dem Rechner installiert.[Im Falle von transcode wird das Programm mit sämtlichen denkbaren Optionen kompiliert, wenn man von der Default-Konfiguration der Quellen ausgeht.] Damit hätten Sie einen einfachen Weg aus dem Abhängigkeitsdschungel beim Kompilieren gefunden.