Der Aufbau eines RPM-Paketes geht normalerweise in den folgenden Schritten vor sich:

  • Einrichten des Quellcodes für das zu bildende Paket.
  • Erstellen eines Patches für alle Veränderungen am Quellcode, die notwendig waren, um das Programm zu erstellen.
  • Erstellen einer SPEC-Datei
  • Sicherstellen, dass alle Dateien an den richtigen Orten installiert sind
  • Aufbau des Paketes mit rpm.

Die ersten beiden Schritte sind nicht weiter erwähnenswert, da sie in vorherigen Kapiteln bereits beschrieben wurden. Wir gehen also davon aus, dass ein Programmpaket im Quellcode vorliegt und dieser Quellcode kompilierbar ist.

Die SPEC-Datei

Die spec-Datei ist die zentrale Informationsquelle für den Prozess des Aufbaus einer RPM-Datei. Sie enthält alle Informationen um ein RPM-Paket zu erstellen, inklusive der Information, was genau in das Paket aufgenommen werden soll und wohin es installiert werden soll.

Eine spec-Datei enthält acht Abschnitte (sections), die ihren Aufbau etwas übersichtlicher machen: Die Präambel Dieser Abschnitt enthält all die Informationen, die später mit Hilfe des rpm-Kommandos ausgegeben werden können. Im Großen und Ganzen sind das weniger die Informationen, die zum Aufbau eines Paketes notwendig sind, sondern mehr die, die später für die User relevant sind. Die Prep-Sektion Dieser Abschnitt beginnt grundsätzlich mit der Zeile %prep. Anschließend folgt ein einfaches Shellscript, das die Befehle enthält, die notwendig sind, den Quellcode-Dateibaum aufzubauen. Normalerweise sind das Befehle wie tar, die ein normales tar-Quellcode Archiv auspacken und in das Verzeichnis wechseln. Die Build-Sektion Wie die Prep-Sektion beginnt auch die Built-Sektion mit einer Zeile %build. Auch hier folgt wieder ein Shellscript, das dazu dient, die notwendigen Schritte durchzuführen, um den Quellcode zu kompilieren. In der Regel reicht hier ein einfaches make. Die Install-Sektion Auch dieser Abschnitt beginnt mit der Zeile %install und enthält ein Shellscript. Normalerweise besteht das Script aus der Zeile make install. Wenn das Paket keine make-Regel zur Installation besitzt, muß in diesem Abschnitt ein eintsprechendes Script stehen, das die Dateien an die entsprechenden Positionen kopiert. Die Files-Sektion Im Gegensatz zu den vorhergehenden Abschnitten enthält diese Sektion kein Shellscript. Statt dessen sind hier alle Dateien angegeben, die in das RPM-Paket übernommen werden sollen. Diese Liste muß von Hand erstellt werden und alle Dateien, die übernommen werden sollen müssen hier mit vollem Pfad angegeben werden. Install- und Uninstall Scripts Dieser Abschnitt besteht eigentlich aus vier Unterabschnitten, die alle Scripts enthalten, die zu verschiedenen Gelegenheiten auf dem Computer ausgeführt werden, auf dem das Paket aufgespielt wird. Die vier Scripts sind:

  • %pre
    Dieses Script wird ausgeführt, bevor die eigentliche Installationsarbeit beginnt. Es wird sehr selten benötigt.
  • %post
    Dieses Script wird ausgeführt, nachdem das Paket installiert wurde. Es kann z.B. benutzt werden, wenn ein Paket ein shared library enthält, um ldconfig auszuführen oder um Systemdateien anzupassen.
  • %preun
    Das Script, das ausgeführt werden soll, bevor ein Paket deinstalliert wird. Ebenfalls sehr selten benutzt.
  • %postun
    Dieses Script wird nach einer Deinstallation aufgerufen. Wieder wird es z.B. benutzt, um ldconfig aufzurufen, wenn das deinstallierte Paket eine shared library enthielt…

Alle vier Scripts sind normale Shellscripts für eine Bourne-Shell. Das Verify-Script Dieser Abschnitt enthält wiederum ein Script, das benutzt werden kann, um die Installation zu überprüfen. Der Abschnitt beginnt mit der Zeile %verifyscript und kann benutzt werden, eventuelle Abhängigkeiten zu überprüfen, die RPM selbst nicht bearbeiten kann. Die Clean-Sektion Ein selten benutzter Abschnitt, der es ermöglicht, Befehle anzugeben, die nach dem Aufbau des Paketes (auf dem Entwickler-Rechner) ausgeführt werden sollen. Der Abschnitt beginnt mit der Zeile %clean.

Um das alles einmal konkret zu machen, spielen wir einmal den Aufbau eines sehr einfachen Paketes durch.

Aufbau eines sehr einfachen Paketes

Wenn wir ein sehr einfaches Paket bauen wollen, dann empfielt es sich, mit etwas sehr simplen zu beginnen, das sich aber an die entsprechenden Regeln hält, die auch bei größeren Paketen angewandt werden würden. Ich habe für diesen Zweck ein sehr einfaches „Hallo-Welt“ Programm geschrieben, das ein entsprechendes Makefile besitzt.

Standardmäßig sollte ein Makefile mindestens die Regeln all und install kennen. Beide Regeln werden von meinem Demoprogramm unterstützt. Zum Ausprobieren habe ich die Dateien hier angehängt:

  • hallo.c
    Der C-Quellcode des Programms
  • Makefile
    Das Makefile für das Programm mit den Regeln all und install.
  • README
    Eine (sehr spärliche) Dokumentation

Diese drei Dateien enthalten alles notwendige für den Aufbau des Paketes. Normalerweise würden wir das Programm mit dem Befehl

  make

kompilieren und anschließend mit

  make install

installieren. Diese Aufgaben sollen jetzt aber durch rpm vorgenommen werden.

Zunächst packen wir das Paket in ein normales tar-Archiv. Dazu erstellen wir ein Verzeichnis, das so heißt, wie das Programm, zusammen mit seiner Versionsnummer. In unserem Beispiel ist das das Verzeichnis hallo-1.0.0. Darin befinden sich jetzt alle drei genannten Dateien (hallo.c, Makefile und README). Wir wechseln ins übergeordnete Verzeichnis und geben den Befehl

  tar -czvf hallo-1.0.0.tar.gz hallo-1.0.0

ein. Dadurch wird das Tar-Archiv hallo-1.0.0.tar.gz erstellt, das das ganze Verzeichnis samt Inhalt enthält. Das ist sozusagen das Orginal-Quellpaket in der Form, wie es vom Entwickler weitergegeben wird.

Wenn rpm auf dem System installiert ist, dann sind auch (meistens) die notwendigen Verzeichnisse für die Paketerstellung schon vorhanden. Standardmäßig liegen sie unter /usr/src/rpm, andere Distributionen können das auch anders machen, SuSE z.B. legt sie unter /usr/src/packages ab. In diesem Verzeichnis liegen fünf weitere Verzeichnisse:

  • BUILD
  • RPMS
  • SOURCES
  • SPECS
  • SRPMS

Die beiden wichtigsten Verzeichnisse für uns sind SOURCES und SPECS. In das Verzeichnis SOURCES kopieren wir jetzt unser tar-Archiv. Wir müssen es nicht entpacken, das erledigt rpm für uns.

Der nächste Schritt ist die Erstellung der SPEC-Datei. Das Verzeichnis SPECS ist der Ort, wo diese Dateien angelegt werden. Wir erstellen in diesem Verzeichnis jetzt eine SPEC-Datei für unser Beispielpaket. Die Datei sollte so heißen, wie unser Programm, wir nennen sie einfach mal hallo.spec.

Die Datei enthält genau die oben genannten Abschnitte, allerdings ohne die entsprechenden Scripts. Sie sieht folgendermaßen aus:


Vendor:         W.Eihnachtsmann
Distribution:   None
Name:           hallo
Release:        13
Packager:       W.Eihnachtsmann <weihnachtsmann@nordpol.com>

Copyright:      GPL
Group:          unsorted
Provides:       hallo
Autoreqprov:    on
Version:        1.0.0
Summary:        Eine einfache Hallo Welt Anwendung
Source:         hallo-1.0.0.tar.gz

%description
Diese Anwendung zeigt die grundlegende Funktionalitaet
eines C-Compilers. Damit auch Nicht-Programmierer dieses
Programm nutzen koennen, habe ich es hier als Binaerpaket
veroeffentlicht.

# Die %prep Sektion entpackt das tar Archiv. (Statt der beiden Anweisungen
# haetten wir auch einfach %setup schreiben koennen.
%prep

rm -rf $RPM_BUILD_DIR/hallo-1.0.0 
zcat $RPM_SOURCE_DIR/hallo-1.0.0.tar.gz | tar -xvf -

# Die %build Sektion kompiliert das Programm
%build

make

# Die %install Sektion installiert es
%install

make install

# Die %files Sektion enthält eine Liste der Dateien, die in das RPM-Paket
# integriert werden sollen. 
%files
/usr/local/bin/hallo
%doc README


Bitte beachten Sie, dass kein einziger Umlaut in dieser Datei vorkommen darf, nicht einmal in den Kommentaren.

Um das Paket jetzt aufzubauen genügt es, in das SPEC-Verzeichnis zu wechseln und den Befehl

  rpm -ba hallo.spec

einzugeben. (-ba bedeutet build all und erstellt sowohl das Binärpaket (.rpm), als auch das Quellcodepaket (.src.rpm)) Jetzt werden folgende einzelnen Schritte ausgeführt:

  1. Die Anweisungen der %prep Sektion werden nacheinander abgearbeitet. Das heißt, das Quellcode-Paket in SOURCES wird im Verzeichnis BUILT ausgepackt, nachdem dort eventuell vorhandene ältere Versionen gelöscht wurden. Dieser Schritt kann einzeln mit dem Befehl rpm -bp SPEC-Datei ausgeführt werden. Hier werden normalerweise auch eventuell notwendige Patches eingespielt.
  2. Die Anweisungen der %build Sektion werden ausgeführt. Das heißt, das Programm wird im gerade erstellten Verzeichnis innerhalb von BUILD kompiliert. Dieser Schritt kann mit dem Befehl rpm -bc SPEC-Datei einzeln abgearbeitet werden (dieser Befehl beinhaltet aber auch -bp).
  3. Die Anweisungen der %install Sektion werden abgearbeitet. Das bedeutet, dass auf dem Entwicklerrechner das Programm jetzt in die entsprechenden Verzeichnisse kopiert wird. Einzeln wird dieser Schritt mit rpm -bi SPEC-Datei ausgeführt.
  4. Anhand der Dateiliste erstellt rpm jetzt das Binärpaket und legt es in das Verzeichnis RPMS ab.
  5. Das Quellpaket wird in SRPMS abgelegt.

Jetzt haben wir die fertigen Pakete erstellt und können sie entsprechend weitergeben oder veröffentlichen.

Eine gute (aber englische) Anleitung gibt es bei RedHat selbst: Taking the Red Hat Package Manager to the Limit