OpenSuse-RPM-Pakete selbst bauen

Aus LinuxUser 05/2025

OpenSuse-RPM-Pakete selbst bauen

© zerbor / 123RF.com

Sicher verpackt

Eine Distribution mit zahllosen auf Abhängigkeiten abgestimmten Paketen zu erstellen, ist eine Aufgabe für Profis. Doch das Auffrischen oder Patchen einzelner Pakete gelingt selbst Durchschnittsanwendern.

Unter OpenSuse genügt für die Installation eines Programms seine Auswahl im YaST-Modul Software (Abbildung 1). Die Voraussetzung für eine komfortable Softwareinstallation schaffen die OpenSuse-Entwickler, indem sie den von den Autoren des Programms in C oder C++ geschriebenen Quellcode kompilieren (also in ein Binärprogramm übersetzen) und in ein RPM-Paket verpacken.

Fortgeschrittene Anwender dürften schon das eine oder andere Programm mit dem bekannten Dreisatz ./configure; make; sudo make install selbst übersetzt und unter Umgehung des Paketmanagements auf ihrem System installiert haben. Auch wenn das Prozedere auf den ersten Blick problemlos funktioniert, birgt es immer das Risiko, Systemdateien zu überschreiben. Die Softwareverwaltung dagegen registriert jede Datei aus den mehreren Tausend installierten Paketen und verhindert ein Überschreiben durch in Konflikt stehende Packages (Abbildung 1).

Abbildung 1: Die Paketverwaltung von OpenSuse installiert Tausende mitgelieferter Pakete. Jede darin enthaltene Datei ist zentral registriert und gegen Überschreiben durch andere, auch selbstgebaute, Pakete gesichert.

Abbildung 1: Die Paketverwaltung von OpenSuse installiert Tausende mitgelieferter Pakete. Jede darin enthaltene Datei ist zentral registriert und gegen Überschreiben durch andere, auch selbstgebaute, Pakete gesichert.

Bei Bedarf finden Sie leicht heraus, welche Pakete installiert sind, wie viel Platz sie belegen und welche Dateien in der Systempartition zu welchem Paket gehören. Legen Sie Wert auf ein stabiles, gut zu verwaltendes OpenSuse-System, sollten Sie Software nicht per make install einspielen, sondern stattdessen selbst Pakete bauen.

Ein RPM-Paket ohne Vorlage zu erstellen, ist aufwendig und setzt einiges Wissen voraus. Viel einfacher gelingt es, ein vorliegendes Paket auf eine neue Version zu aktualisieren oder einen noch nicht offiziell veröffentlichten Patch (einen sogenannten Hotfix) anzuwenden. Wir zeigen im Folgenden, wie das auf OpenSuse-Systemen funktioniert.

Vorbereitungen

Installieren Sie zunächst die Pakete rpm-build und rpmdevtools und rufen dann rpmdev-setuptree auf. Der Befehl erzeugt in Ihrem Home das Verzeichnis rpmbuild/ samt einiger Unterordner.

Alle Distributionen stellen den Quellcode zu ihren Paketen schon deshalb bereit, weil die Masse der Software unter der GPL-Lizenz steht. Ein sudo zypper si Paket oder sudo zypper source-install Paket lädt den Quellcode nach /usr/src/packages/ herunter. Dort finden sich Unterverzeichnisse mit denselben Namen wie unter $HOME/rpmbuild/. Außerdem installiert der Zypper-Aufruf die Build-Dependencies des Pakets, sprich die Devel-Pakete, einen Compiler, Build-Systeme wie Make und weitere erforderliche Komponenten.

Der Quellcode für den Bau eines Pakets besteht aus dem Quellcode der im Paket enthaltenen Software und einer SPEC-Datei (Abbildung 2), der Steuerdatei für den Paketbau. Ein Blick in den Ordner SOURCES/ nach Ausführen des Befehls zypper si zeigt, dass sich zum eigentlichen Quellcode der Software oft noch Hilfsdateien wie READMEs oder sogenannte Patches gesellen. Deren Funktion werden wir später noch im Detail kennenlernen.

Abbildung 2: Ein <code>zypper si hugin</code> hat die SPEC-Datei und das Quellcodearchiv f&uuml;r Hugin in die Unterverzeichnisse von <code>~/rpmbuild/</code> geladen, hier manuell um eine neuere Version erg&auml;nzt.

Abbildung 2: Ein zypper si hugin hat die SPEC-Datei und das Quellcodearchiv für Hugin in die Unterverzeichnisse von ~/rpmbuild/ geladen, hier manuell um eine neuere Version ergänzt.

Den SPEC-Dateien entnimmt das fertige Paket Namen und Version sowie weitere Daten wie die Lizenz und die Homepage des Programms. Vor allem enthalten sie die Befehle, die den Quell- in Maschinencode übersetzen.

Der Aufruf zypper legt die Quelldateien in nur mit Root-Rechten beschreibbaren Verzeichnissen der Systempartition ab. Aus Sicherheitsgründen sollte der Paketbau jedoch stets mit Benutzerrechten erfolgen. Kopieren Sie daher die Verzeichnisse SOURCES/ und SPECS/ samt Inhalt ins Verzeichnis $HOME/rpmbuild/. Da die Dateien für alle per zypper si heruntergeladenen Pakete in denselben Verzeichnissen landen, sollten Sie diese nach dem Bau eines Pakets leeren; die Dateien dort sind leicht wiederzubeschaffen.

Aus eigener Produktion

Sie haben mit zypper si die offiziellen Quellen eines Pakets aus dem OpenSuse-Repository heruntergeladen. Rufen Sie nun rpmbuild -bb SPEC-Datei auf, um lokal ein mit dem offiziellen OpenSuse identisches Paket zu bauen. Die Option -bb steht für “build binary”, also den Bau eines Binärpakets aus dem Quellcode.

Es gehört zum Wesen einer quelloffenen Distribution, dass jeder Anwender den Paketbauvorgang, den genutzten Quellcode und die angewandten Patches und Hotfixes jedes einzelnen mitgelieferten Softwarepakets genau nachvollziehen kann. Es bringt in der Praxis wenig, die bereits vorliegenden Pakete zu replizieren, außer Sie möchten den Maschinencode für ein spezielles Prozessormodell optimieren und so mehr Performance herauskitzeln. Dazu gilt es, eine Reihe von Umgebungsvariablen [2] in die SPEC-Files einzubinden. Passende Werte für die Variablen nennt das Arch-Linux-Wiki [3].

Es lohnt sich zudem, den Paketbau auf einem neueren System mit den Paketquellen aus einer älteren OpenSuse-Version zu versuchen: Die Erfolgsaussichten sind dann besser als bei der Installation eines veralteten Programmpakets. Der Paketbauprozess legt die Abhängigkeiten notgedrungen auf die Bibliotheksversionen des Build-Systems fest, um die Funktion zu gewährleisten. Beim erneuten Kompilieren mit anderen Versionen zeigt sich oft, dass diese Bindung unnötig starr ausfällt, doch Rpmbuild kann das nur für das konkrete System entscheiden, auf dem es aufgerufen wird.

Meist dient der Paketbau in Eigenregie dazu, eine neuere Softwareversion bereitzustellen. Da die OpenSuse-Entwickler solche Aktualisierungen für eine neue Ausgabe der Distribution an Tausenden Paketen vornehmen, liegt die Vermutung nahe, dass das ohne großen Aufwand klappt. Tatsächlich genügt es in vielen Fällen, in der SPEC-Datei, einer reinen Textdatei, die dort hinterlegte Versionsnummer zu erhöhen und eine aktuelle Version des Quellcodes in das Verzeichnis SOURCES/ herunterzuladen.

Ein Beispiel, bei dem das im Test auf Anhieb funktionierte, ist das Leap-Paket für Hugin (Abbildung 3), ein Tool zum automatischen Zusammenfügen von Panoramakacheln [4]. In den OpenSuse-Repositories von Leap 15.6 steht das Programm in Version 2023.0 bereit, während die Hugin-Homepage den Quellcode für die Version 2024.0.1 zum Herunterladen anbietet.

Abbildung 3: Das Programm Hugin zum Zusammenf&uuml;gen von Panoramen l&auml;uft auf diesem Leap-System in der mittels eines selbstgebauten Pakets aufgefrischten Version 2024.0.1.

Abbildung 3: Das Programm Hugin zum Zusammenfügen von Panoramen läuft auf diesem Leap-System in der mittels eines selbstgebauten Pakets aufgefrischten Version 2024.0.1.

Öffnen Sie die SPEC-Datei ~/rpmbuild/SPECS/hugin.spec in einem Texteditor (Abbildung 4). Sie ist über 600 Zeilen lang, wovon allerdings Changelog-Einträge den Löwenanteil ausmachen. Wir wollen das Paket mit aktualisiertem Quellcode bauen, wodurch sich die Version des Pakets ändert. Relevant sind daher die Datenfelder Version: und Source: in der SPEC-Datei.

Abbildung 4: In der SPEC-Datei f&uuml;r das Hugin-Paket haben wir lediglich die drei rot markierten Bereiche ver&auml;ndert, um die Software auf eine neuere Version zu aktualisieren.

Abbildung 4: In der SPEC-Datei für das Hugin-Paket haben wir lediglich die drei rot markierten Bereiche verändert, um die Software auf eine neuere Version zu aktualisieren.

SPEC-Dateien enthalten drei Strukturelemente: einzeilige Datenfelder wie Version: oder Name:, Makros [5] wie %define oder %cmake sowie die mehrzeiligen Datenfelder %description, %prep, %build, %install, %files und %changelog. Das Kommando rpmbuild -E %Makro zeigt die konkreten Kommandozeilenbefehle, zu denen ein bestimmtes Makro auf dem System expandiert.

Während %description rein beschreibende Daten liefert, enthalten die mehrzeiligen Datenfelder %prep, %build und %install die Konsolenbefehle, mit denen Rpmbuild den in Source: genannten Quellcode beim Paketbau kompiliert. Der Abschnitt %files besteht aus einer Liste aller Dateien, die das Paket enthalten soll. Hier sind die gleichen Glob-Operatoren (*) erlaubt wie beim Ls-Befehl auf der Konsole.

Die Liste muss alle in den Schritten %build und %install erzeugten Dateien erfassen (Abbildung 5), sonst bricht die Paketerstellung mit einer Fehlermeldung ab. Das soll verhindern, dass bei einem Update unbemerkt neue Dateien ins Paket gelangen. Eine stets gültige Dateiliste lautet /*. Dieser Glob-Ausdruck über alle Dateien unterhalb des Root-Verzeichnisses erfasst garantiert alle beim Kompilieren entstandenen Dateien. Das hebelt dann freilich das vorgesehene Sicherheitsnetz komplett aus.

Abbildung 5: Der Abschnitt <code>%files</code> der SPEC-Datei muss entweder explizit oder per <code>*</code> alle beim Kompilieren entstandenen Dateien abbilden.

Abbildung 5: Der Abschnitt %files der SPEC-Datei muss entweder explizit oder per * alle beim Kompilieren entstandenen Dateien abbilden.

Direkt von der Quelle

Bei unserem Beispiel, dem Update von Hugin 2023.0 auf Version 2024.0.1, treten im Abschnitt %files aber ohnehin keine Probleme auf. Kümmern wir uns also zunächst um einen aktualisierten Quellcode von der Hugin-Webseite, die praktischerweise das Feld URL: in der SPEC-Datei nennt: Unter http://hugin.sourceforge.net finden Sie einen Download-Link, der auf die aktuelle Version des Quellcodes verweist, den Tarball hugin-2024.0.1.tar.bz2. Speichern Sie diese Datei im Unterverzeichnis ~/rpmbuild/SOURCES/.

In der SPEC-Datei hugin.spec folgt auf den einleitenden Kommentarblock die Definition der Variablen mversion, woraus im Feld Version: durch Anhängen von .0 die eigentliche Paketversion entsteht. In das Feld Source: gehört dagegen die Major-Version ohne angehängte letzte Stelle, um die richtige Download-URL zu erzeugen. Die Internetadresse des Quellcodes ist an dieser Stelle jedoch nur für den OpenSuse-Build-Service relevant, der das Quellarchiv automatisch herunterlädt. Rpmbuild kümmert sich darum nicht, es durchsucht lediglich das lokale Verzeichnis SOURCES/. Deshalb muss in einer SPEC-Datei für den lokalen Einsatz unter Source: keine vollständige URL stehen, es genügt ein Dateiname.

Sie können also die Zeile %define mversion 2023.0 löschen. Unter Source: tragen Sie den Namen des eben heruntergeladenen Tarballs ein, sprich hugin-2024.0.1.tar.bz2; das Feld Version: aktualisieren Sie auf 2024.0.1 (Abbildung 4). Abschließend sollten Sie noch das Release:-Feld verändern, zum Beispiel auf den Wert mypkgs.1. Dieser Release-String erscheint zum einen im Dateinamen des RPMs, zum anderen zeigt ihn der Paketmanager nach der Installation des Pakets an. Ein zu langer Wert führt zu unhandlichen Dateinamen. Es ist aber nützlich, wenn Sie später aus dem Release-String schließen können, dass es sich um Version 1 eines von Ihnen selbst gebauten Pakets handelt.

Jetzt starten Sie mit rpmbuild -bb /Pfad/zu/hugin.spec den Paketbau. Das Kompilieren aus dem Quellcode dauert je nach CPU-Leistung unterschiedlich lange. Sehen Sie gegen Ende der langen Reihe der über das Konsolenfenster wandernden Ausgabezeilen die Meldung Wrote: /home/User/rpmbuild/RPMS/x86_64/hugin-2024.0.1-mypkgs.1.x86_64.rpm, war Ihre Mühe von Erfolg gekrönt (Abbildung 6).

Abbildung 6: Erscheint die Nachricht, dass Rpmbuild eine oder mehrere Paketdateien geschrieben hat, war der Vorgang erfolgreich.

Abbildung 6: Erscheint die Nachricht, dass Rpmbuild eine oder mehrere Paketdateien geschrieben hat, war der Vorgang erfolgreich.

Mit Benutzerrechten gebaute Pakete landen im Ordner RPMs/, Pakete mit ausführbarem Code im Unterverzeichnis x86_64/, Sprachpakete und andere ohne ausführbaren Code im Ordner noarch/. Sie installieren das neue Hugin-Paket mit dem Kommando aus Listing 1. Warnungen bezüglich der nicht signierten Datei dürfen Sie getrost ignorieren: Lokal erzeugte Pakete unterliegen nicht der Gefahr der Manipulation während des Herunterladens.

Listing 1

Installationskommando

$ zypper ~/rpmbuild RPMS/x86_64/hugin-2024.0.1-mypkgs.1.x86_64.rpm

Im Fall von Hugin gelingt das Update auf eine neuere Version unter Leap 15.6 reibungslos. Es gibt jedoch zahllose Gründe für einen potenziellen Fehlschlag: Möglicherweise haben die Entwickler den Code für neuere Bibliotheken oder eine neuere Compiler-Version umgeschrieben, eventuell gibt es schlicht neue Abhängigkeiten (Abbildung 7). Die Entwickler bemerken solche Probleme meist nicht, denn es fehlt ihnen die Zeit, ihre Software auf allen verbreiteten Distributionen zu testen.

Abbildung 7: Das Build-System, hier Cmake, beschwert sich vor dem Kompilieren, dass es die ben&ouml;tigte Komponente <code>VIGRA</code> nicht finden kann.

Abbildung 7: Das Build-System, hier Cmake, beschwert sich vor dem Kompilieren, dass es die benötigte Komponente VIGRA nicht finden kann.

Möchten Sie RPMs für Programme bauen, für die es bisher kein Paket gibt, müssen Sie zunächst wissen, wie Sie die Software aus dem Quellcode kompilieren. Nicht immer liefert die Homepage einer Software konkrete Hinweise dazu. Als Einstiegslektüre für RPM-Paketbau-Adepten empfiehlt sich der nicht OpenSuse-spezifische englische RPM Packaging Guide [6]. Von Suse gibt es eine ebenfalls englische, weniger umfangreiche Einführung [7] in das Thema. Als nützlich erweist sich daneben der größtenteils übertragbare RPM Packaging Guide von Fedora [8].

In der Praxis verläuft der Paketbau inklusive des stets damit verbundenen Kompilierens aus dem Quellcode nach dem Prinzip Versuch und Irrtum. Dabei gilt es, sich sukzessive die teils spezifischen und teils wiederkehrenden Fehlermeldungen per Internetrecherche zu erschließen.

Trostpflaster

Oft finden sich im Internet Lösungen für Bugs, die Softwareentwickler noch nicht in einem neuen Release veröffentlicht haben. Solche Hotfixes liegen in Form einer Patch-Datei vor. Dabei handelt es sich um Textdateien, die Änderungen im Quellcode einer Software im sogenannten Unified-Diff-Format festhalten. Jede Änderung ist hier mithilfe von drei vorangehenden und folgenden unveränderten Zeilen im Quellcode verankert. Auf diese Weise bleibt ein Patch selbst nach kleinen Veränderungen der Software noch anwendbar, weil er sich nicht rein auf Zeilennummern stützt. Auch die Hugin-SPEC-Datei verarbeitet einen solchen Patch: Die OpenSuse-Entwickler haben dabei die Schreibweise in den Startmenüeinträgen angepasst.

Rsibreak (Abbildung 8) aus dem KDE-Umfeld, das zum Einhalten von Bildschirmpausen animiert, liefert ein Paradebeispiel für ein Programm, bei dem sich der Anwender dringend einen Hotfix wünscht: Seit Jahren funktioniert die Anwendung nicht unter Wayland. Dort erkennt Rsibreak die Inaktivität von Maus und Tastatur nicht und hebt daher die Bildschirmsperrung nicht nach der konfigurierten Ruhezeit auf.

Abbildung 8: Rsibreak erinnert daran, kurze Pausen einzulegen. Ein bislang von den Entwicklern nicht &uuml;bernommener Patch r&uuml;stet es f&uuml;r Wayland-Sitzungen.

Abbildung 8: Rsibreak erinnert daran, kurze Pausen einzulegen. Ein bislang von den Entwicklern nicht übernommener Patch rüstet es für Wayland-Sitzungen.

Tatsächlich hat ein externer Programmierer einen Patch eingereicht [9], der das Problem löst, allerdings auf eine von den Rsibreak-Entwicklern verworfene, ineffiziente Art und Weise. Dessen ungeachtet ist der Hotfix im Moment die einzige Lösung für Wayland-Anwender. Allerdings benötigt der vier Jahre alte Patch eine leichte Anpassung, damit er sich auf die zwei Jahre alte OpenSuse-Leap-Fassung des Quellcodes anwenden lässt. Den entsprechenden Patch finden Sie bei Interesse in Form der Datei rsibreak_wayland.patch im Download-Bereich zu diesem Artikel, von wo Sie ihn ins Verzeichnis $HOME/rpmbuild/SOURCES/ herunterladen.

Installieren Sie für eine lokale Paketerstellung wie im Hugin-Beispiel die Quelldateien und kopieren Sie den Inhalt der Ordner SOURCES/ und SPECS/ aus /usr/src/packages/ in die entsprechenden Verzeichnisse in Ihrem Home (Listing 2). Bearbeiten Sie dann die Datei rsibreak.spec. Zuerst registrieren Sie die Patch-Datei mit der Zeile Patch0: rsibreak_wayland.patch, die Sie am besten vor den BuildRequires-Zeilen platzieren. Auf jeden Fall muss sie außerhalb des in der SPEC-Datei für Rsibreak zu findenden %if%endif-Blocks stehen (Abbildung 9).

Listing 2

Rsibreak-Quellen

$ sudo zypper si rsibreak
$ cp /usr/src/packages/SOURCES $HOME/rpmbuild/SOURCES
$ cp /usr/src/packages/SPECS $HOME/rpmbuild/SPECS

Abbildung 9: Zwei Ver&auml;nderungen an der SPEC-Datei f&uuml;r Rsibreak wenden den Wayland-Timer-Patch an und machen das Programm f&uuml;r das zeitgem&auml;&szlig;e Display-System tauglich.

Abbildung 9: Zwei Veränderungen an der SPEC-Datei für Rsibreak wenden den Wayland-Timer-Patch an und machen das Programm für das zeitgemäße Display-System tauglich.

Rpmbuild automatisiert das eigentliche Anwenden des Patches mithilfe des GNU-Tools Patch. Sie müssen dafür lediglich das Makro %setup -q zu Beginn des %prep-Blocks durch %autosetup -q1 ersetzen. Dieses Autosetup-Makro wendet automatisch alle per PatchX: eingebundenen Patches auf den Quellcode an und reicht dabei die angehängte Option -q1 (also die Patch-Datei) an Patch durch.

Damit hat es Folgendes auf sich: Beim Erstellen eines Patches vergleichen die Entwickler mit dem Tool Diff den unveränderten Quellcode im Ordner a/rsibreak mit dem veränderten unter b/rsibreak. Die Optionen -p respektive --strip sorgen dafür, dass Patch den ersten vorgeschalteten Pfadabschnitt a/ und b/ ignoriert. Nach diesen Änderungen an der SPEC-Datei erstellt rpmbuild -bb /Pfad/zu/rsibreak.spec ein Paket mit integrierten Hotfix. Nach der Installation dieses selbstgebauten RPMs funktioniert Rsibreak auch in Wayland-Sitzungen.

Fazit

Der Paketbau gilt als schwieriges Geschäft, das die meisten Anwender lieber Spezialisten überlassen. Tatsächlich ist es keine einfache Aufgabe, Tausende Pakete bereitzustellen, die alle in ihren Abhängigkeiten harmonieren müssen. Doch mit etwas Know-how gelingt es auch Heimanwendern, einzelne Pakete auf eine neuere Version aufzufrischen oder einen Hotfix anzuwenden, der es noch nicht in die Repos der Distribution geschafft hat. (uba/jlu)

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 05/2025 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben