Website-Suche

So erstellen Sie ein RPM-Paket


Rpm ist sowohl der Paketmanager als auch das Paketformat, das von vielen Linux-Distributionen wie Fedora, Red Hat und CentOS verwendet wird, um Software in binärer Form zu verwalten und zu verteilen. In diesem Tutorial sehen wir, wie man eine einfache Anwendung erstellt und verpackt.

In diesem Tutorial lernen Sie:

  • Was sind die grundlegenden Konzepte hinter dem RPM-Bauprozess?
  • Was ist die Buildumgebung?
  • Was ist eine Spezifikationsdatei?
  • Wie man Makros in einer Spezifikationsdatei verwendet.
  • So installieren Sie die Buildabhängigkeiten.
  • So erstellen Sie eine Spezifikationsdatei.
  • Wie man ein RPM-Paket erstellt.

Verwendete Softwareanforderungen und Konventionen

Rpm Grundbegriffe

Das Installieren, Entfernen, Aktualisieren (mit einem Wort, Verwalten) von Software ist eine wesentliche Aufgabe auf jedem Betriebssystem. Als es noch keine Paketmanager gab, bestand die einzige Möglichkeit, ein Programm zu installieren, darin, seinen Quellcode zu kompilieren und die resultierenden Dateien an den entsprechenden Stellen im Dateisystem abzulegen. Es war wirklich schwierig und zeitaufwändig, den Überblick über die Abhängigkeiten der einzelnen Codeteile zu behalten. Dann wurden Paketmanager eingeführt, und alles wurde einfacher.

Jede moderne Linux-Distribution hat heutzutage ihren Paketmanager: Debian und seine Derivate verwenden dpkg, während
rpm in der Red Hat-Distributionsfamilie verwendet wird. Die Software wird vorkompiliert in Form von Paketen bereitgestellt, bei denen es sich im Grunde um komprimierte Archive handelt, die Metadaten über die Softwareversion, ihre Abhängigkeiten und mögliche Konflikte mit anderen Paketen enthalten.

In diesem Tutorial sehen wir, wie Sie ein RPM-Paket ausgehend von einem Anwendungsquellcode erstellen. Die Anwendung, die wir packen werden, ist feh, ein einfacher Befehlszeilen-Bildbetrachter: Er ist ziemlich klein und hat nur wenige Abhängigkeiten. Bevor wir jedoch mit der Erstellung unseres ersten Pakets beginnen, gibt es einige wesentliche Konzepte, die wir verstehen sollten.

Die Build-Umgebung

Der Stamm eines RPM-Build-Umgebungsbaums ist das Verzeichnis rpmbuild, das 6 Unterverzeichnisse enthält: BUILD, BUILDROOT, RPMS, SOURCES, SPECS und SRPMS. Wir werden sehen, wie es möglich ist, diese Umgebung durch Starten eines einfachen Befehls zu generieren; Lassen Sie uns zunächst nur die Rolle dieser Verzeichnisse erwähnen. Hier ist eine Darstellung des Arbeitsbaums:

  rpmbuild
  |-- BUILD
  |-- BUILDROOT
  |-- RPMS
  |-- SOURCES
  |-- SPECS
  |-- SRPMS

Jedes dieser Verzeichnisse spielt eine bestimmte Rolle im Erstellungsprozess:

  • Das BUILD-Verzeichnis ist der Ort, an dem der Quellcode des Programms erstellt wird, das wir packen möchten
  • Das BUILDROOT-Verzeichnis ist der Ort, an den die Dateien kopiert werden, die aus der Kompilierung der Software im BUILD-Verzeichnis resultieren, was die Struktur des Zielsystems in einem Unterverzeichnis mit dem Paket mame:
    widerspiegelt. In unserem Fall wird die Binärdatei "feh", die in /usr/bin installiert würde, als BUILDROOT/feh-3.0-1.fc29.x86_64/usr/bin gemeldet.
  • Das RPMS-Verzeichnis ist der Ort, an dem RPM-Pakete generiert werden: Jedes RPM wird in einem Unterverzeichnis abgelegt
    , das nach seiner Architektur benannt ist, oder noarch, wenn es nicht architekturspezifisch ist.
  • Das SOURCES-Verzeichnis hostet den komprimierten Quellcode der Software, die wir paketieren möchten, oft in Form eines Tarballs einer Zip-Datei.
  • Das SPECS-Verzeichnis ist der Ort, an dem wir die .spec-Datei mit den Anweisungen zum Erstellen unseres Pakets ablegen: Wir werden die Struktur dieser Datei gleich analysieren.
  • Das SRPMS-Verzeichnis ist das Äquivalent zu RPMS, jedoch für Quell-RPMS. Diese speziellen Pakete enthalten den ursprünglichen Quellcode der Anwendung, eventuelle Patches und die Spezifikationsdatei, die zum Erstellen des Pakets verwendet wurde.

Die Spezifikationsdatei

Die Datei, in der alle Anweisungen und Informationen definiert sind, die zum Erstellen eines RPM-Pakets benötigt werden, ist die .spec-Datei. Ein Specfile enthält unter anderem die Build-Abhängigkeiten (die Software, die zum Kompilieren des Programms benötigt wird, das wir packen möchten), die Laufzeitabhängigkeiten (die Bibliotheken, die für den korrekten Betrieb des Programms benötigt werden) und die Befehle, die ausgeführt werden sollen, um die Software zu kompilieren.

Die Datei besteht aus zwei Makroabschnitten: einer Präambel und dem Hauptteil. In jedem dieser Abschnitte können unterschiedliche Anweisungen angegeben werden. Schauen wir uns einige von ihnen an. Der Abschnitt der Präambel kann die folgenden Anweisungen enthalten:

    • Name: Der Basisname des Pakets (dieser sollte mit dem Namen der Spezifikationsdatei übereinstimmen)
    • Version: Die Upstream-Version der verpackten Software
    • Release: Die Release-Nummer des Pakets
    • Lizenz: Die Lizenz, die für die Software verwendet wird, die wir verpacken möchten
    • Url: Die Upstream-URL der Software
    • Source0: Die direkte URL oder der Pfad des komprimierten Quellcodes der Software (Tarball oder gezippte Datei)
    • BuildArch: Die Architektur des Pakets: Wenn keine Architektur angegeben ist, wird die des Host-Systems verwendet
    • BuildRequires: Die Abhängigkeiten, die zum Erstellen der Software erforderlich sind
    • Erfordert: Die Abhängigkeiten, die zum Ausführen der Software erforderlich sind

Der body-Abschnitt der Spezifikationsdatei enthält in der Regel die folgenden Abschnitte:

  • %description: Eine optional mehrzeilige Beschreibung der verpackten Software
  • %prep: Die Befehle, die zum Vorbereiten des Quellcodes benötigt werden (z. B. die Befehle, die zum Extrahieren eines Tarballs benötigt werden)
  • %build: Der/die Befehl(e), der/die zum Erstellen der Software benötigt wird/werden
  • %install: Der/die Befehl(e), die zum Kopieren der Datei, die aus dem Build-Prozess resultiert(en), in das BUILDROOT-Verzeichnis benötigt werden
  • %files: Die Liste der Dateien, die vom Paket bereitgestellt werden, das auf dem System installiert wird

Makros

Um unsere Arbeit zu erleichtern, können wir innerhalb einer Spezifikationsdatei einige Makros verwenden, die es uns ermöglichen, viele nützliche Dinge zu referenzieren und bestimmte Aufgaben automatisch auszuführen. Zunächst einmal haben wir die RPM-Verzeichnismakros, mit denen die Verzeichnisse unserer Build-Umgebung referenziert werden können. Wir sollten sie immer anstelle von direkten Wegen verwenden:

  • %{_topdir}: Dieses Makro verweist auf das Verzeichnis rpmbuild
  • %{_builddir}: Verweist auf das BUILD-Verzeichnis in unserem Build-Baum
  • %{_rpmdir}: Verweist auf den Pfad des RPMS-Verzeichnisses
  • %{_sourcedir}: Dieses Makro wird in den Pfad des Verzeichnisses SOURCES ausgewertet
  • %{_specdir}: Ein Makro, das den Pfad des SPECS-Verzeichnisses darstellt
  • %{_srcrpmdir}: Verweist auf den Pfad des SRPMS-Verzeichnisses
  • %{_buildrootdir}: Verweist auf den Pfad des BUILDROOT-Verzeichnisses

Andere Makros lassen uns auf die wichtigsten Verzeichnisse im Dateisystem unserer Maschine verweisen, zum Beispiel:

  • %{_sysconfigdir}: Das Verzeichnis /etc
  • %{_prefix}: Das Verzeichnis /usr
  • %{_bindir}: Das Verzeichnis /usr/bin
  • %{_mandir}: Der Pfad zum Verzeichnis /usr/share/man

Die obige Liste ist nicht vollständig, aber sie gibt Ihnen eine Idee. Zusätzlich können wir auch eine Reihe von Makros verwenden, die bestimmte Aufgaben ausführen. Um die Definition eines Makros zu erweitern und so seinen Inhalt zu sehen, können wir den Befehl rpm --eval verwenden, der das Makro als Argument verwendet. Hier sind einige Beispiele für häufig verwendete Makros:

  • Das %setup-Makro wird im Abschnitt %config der Spezifikationsdatei verwendet und führt im Wesentlichen die folgenden Aktionen aus:

    1. Extrahiert den Quellcode des Programms, das wir packen möchten, in das Verzeichnis BUILDDIR
    2. Wechselt in das extrahierte Verzeichnis
    3. Legt die entsprechenden Dateiberechtigungen darin fest
  • Das %{make_build}-Makro wird in der %build-Sektion der Spezifikationsdatei verwendet und führt im Grunde den make-Befehl mit einem vordefinierten Satz von Optionen aus, um den Quellcode der Software zu kompilieren. Wenn wir es erweitern, können wir den Befehl überprüfen, den es ausführt:

    rpm --eval "%{make_build}"
    /usr/bin/make -O -j4
    
  • Das Makro %{make_install} wird stattdessen im Abschnitt %install der Datei verwendet und führt make install mit dem Parameter DESTDIR aus, der verwendet wird, um den Befehl anzuweisen, die kompilierten Dateien relativ zu einem bestimmten Verzeichnis statt zum realen System / zu installieren:

    rpm --eval "%{make_install}"
    /usr/bin/make install DESTDIR=/home/egdoc/rpmbuild/BUILDROOT/%{NAME}-%{VERSION}-%{RELEASE}.x86_64 INSTALL="/usr/bin/install -p"
    

So erstellen Sie ein RPM-Paket Schritt für Schritt Anleitung

Nachdem wir nun das grundlegende Konzept des Paketerstellungsprozesses kennengelernt haben, können wir sehen, wie wir unsere Build-Umgebung und unser erstes rpm-Paket erstellen. Lassen Sie uns unser Paket erstellen.

Installieren der Buildabhängigkeiten

Als erstes müssen wir rpmdevtools installieren, plus die Abhängigkeiten, die zum Erstellen von feh benötigt werden:

sudo dnf install rpmdevtools gcc make imlib2-devel libjpeg-devel libpng-devel libXt-devel libXinerama-devel libexif-devel \
  perl-Test-Command perl-Test-Harness libcurl-devel

Sobald die Pakete installiert sind, können wir unsere Build-Umgebung generieren. Alles, was wir tun müssen, ist, den folgenden Befehl zu starten:

rpmdev-setuptree

An diesem Punkt sollten das rpmbuild-Verzeichnis und alle Unterverzeichnisse, die wir zuvor gesehen haben, erstellt werden. Der nächste Schritt besteht darin, unser Specfile zu schreiben.

Erstellen Sie die Spezifikationsdatei

Wir erstellen das Specfile mit unserem bevorzugten Texteditor und speichern es im SPECS-Verzeichnis mit dem gleichen Namen wie das Paket. So sollte eine minimale Spezifikationsdatei aussehen:

Name:           feh
Version:        3.0
Release:        1%{?dist}
Summary:        Fast command line image viewer using Imlib2
License:        MIT
URL:            http://feh.finalrewind.org
Source0:        http://feh.finalrewind.org/feh-%{version}.tar.bz2

BuildRequires:  gcc
BuildRequires:  imlib2-devel
BuildRequires:  libcurl-devel
BuildRequires:  libjpeg-devel
BuildRequires:  libpng-devel
BuildRequires:  libXt-devel
BuildRequires:  libXinerama-devel
BuildRequires:  libexif-devel
BuildRequires:  perl-Test-Command
BuildRequires:  perl-Test-Harness

%description
Fast command line image viewer using Imlib2

%prep
%setup -q

%build
%{make_build}

%install
%{make_install} PREFIX=%{_prefix}

%files
/usr/bin/feh
/usr/lib/debug/usr/bin/feh-3.0-1.fc29.x86_64.debug
/usr/share/applications/feh.desktop
/usr/share/doc/feh/AUTHORS
/usr/share/doc/feh/ChangeLog
/usr/share/doc/feh/README.md
/usr/share/doc/feh/TODO
/usr/share/doc/feh/examples/buttons
/usr/share/doc/feh/examples/find-lowres
/usr/share/doc/feh/examples/keys
/usr/share/doc/feh/examples/themes
/usr/share/feh/fonts/black.style
/usr/share/feh/fonts/menu.style
/usr/share/feh/fonts/yudit.ttf
/usr/share/feh/images/feh.png
/usr/share/feh/images/feh.svg
/usr/share/feh/images/menubg_default.png
/usr/share/icons/hicolor/48x48/apps/feh.png
/usr/share/icons/hicolor/scalable/apps/feh.svg
/usr/share/man/man1/feh.1.gz

Lassen Sie es uns analysieren. Zuerst haben wir einige grundlegende Informationen über die Software angegeben, die wir paketieren möchten: ihren Namen und ihre Upstream-Version, ihre Lizenz, den Standort der Projekthauptseite und den direkten Link zum Quellcode-Tarball, dann haben wir die Build-Abhängigkeiten mit BuildRequires deklariert. Die Liste der Abhängigkeiten kann als durch Leerzeichen oder Kommas getrennte Inline-Liste dargestellt werden, aber aus Gründen der Lesbarkeit haben wir eine Abhängigkeit pro Zeile deklariert und die BuildRequires-Anweisung wiederholt.

Nachdem wir die Abhängigkeiten deklariert hatten, die zum Erstellen der Software erforderlich sind, haben wir eine kurze Beschreibung im Abschnitt %description bereitgestellt und sind dann zum wichtigsten Teil der Spezifikationsdatei übergegangen: den Anweisungen zum Vorbereiten, Erstellen und Installieren der Software in den Abschnitten %prep, %build und %install.

Im %prep-Abschnitt reichte es aus, das Makro %setup -q bereitzustellen: Wie bereits erwähnt, führt dieses Makro die Befehle aus, die zum Entpacken des Quell-Tarballs und zum Platzieren des extrahierten Verzeichnisses im BUILD-Ordner erforderlich sind.

Im Abschnitt %build geben wir die Befehle an, die ausgeführt werden sollen, um den Quellcode zu erstellen. Selbst hier mussten wir nur das %{make_build}-Makro verwenden, das den make-Befehl mit den zuvor gesehenen Optionen in das Verzeichnis ausführt, in dem sich der entpackte Quellcode der Anwendung befindet, die wir packen möchten.

Im Abschnitt %install haben wir ein weiteres Makro, %{make_install}, verwendet, das auch den Parameter PREFIX bereitstellt und ihn auf %{_prefix} setzt, der in /usr erweitert wird. Der resultierende Befehl bewirkt, dass die Dateien, die durch die Kompilierung des Quellcodes erzeugt werden, in der "gefälschten Wurzel" abgelegt werden, die mit dem im Makro enthaltenen Parameter DESTDIR gesetzt wurde. Da im Makro %{make_install} "DESTDIR" auf /home/egdoc/rpmbuild/BUILDROOT/%{NAME}-%{VERSION}-%{RELEASE}.x86_64 gesetzt ist, werden die Dateien unter: /home/egdoc/rpmbuild/BUILDROOT/%{NAME}-%{VERSION}-%{RELEASE}.x86_64/usr installiert.

Schließlich haben wir im Abschnitt %files eine Liste der Dateien bereitgestellt, die von unserem Paket installiert werden. Diese Liste kann später überprüft werden, indem der Befehl rpm -qlp /path/to/the/rpm ausgeführt wird oder, wenn das Paket bereits installiert ist, einfach rpm -ql packagename ausgeführt wird.

Holen Sie sich die Quellen und erstellen Sie das RPM-Paket.

Jetzt, da unsere Spezifikationsdatei endlich fertig ist, können wir unsere Drehzahl erstellen. Sie werden vielleicht bemerken, dass wir den Quell-Tarball von "feh" noch nicht heruntergeladen haben: Es besteht keine Notwendigkeit, dies manuell zu tun, da wir den Befehl spectool verwenden können:

spectool -g -R ~/rpmbuild/SPECS/feh.spec
Getting http://feh.finalrewind.org/feh-3.0.tar.bz2 to /home/egdoc/rpmbuild/SOURCES/feh-3.0.tar.bz2
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   185  100   185    0     0    898      0 --:--:-- --:--:-- --:--:--   898
100 2057k  100 2057k    0     0  1988k      0  0:00:01  0:00:01 --:--:-- 4191k

Dieser Befehl lädt die Quellen, auf die wir verwiesen haben, mit einer URL innerhalb der Spezifikationsdatei in das entsprechende Verzeichnis unseres Arbeitsbaums herunter: ~/rpmbuild/SOURCES. Mit den Quellen an Ort und Stelle können wir unser rpm erstellen: Alles, was wir tun müssen, ist, den Befehl rpmbuild zu starten und den Pfad zum specfile anzugeben. Wenn rpmbuild mit der Option -bb gestartet wird, erstellt es nur ein Binärpaket: Wenn wir auch ein Quell-rpm erzeugen wollen, müssen wir stattdessen -ba verwenden (konsultieren Sie die rpmbuild-Manpage für einen Überblick über die möglichen Optionen).

Eine sehr wichtige Sache, die Sie sich merken sollten, ist, dass der Befehl rpmbuild niemals mit Root-Rechten gestartet werden sollte: Wenn Sie dies tun, kann selbst ein einfacher Fehler in der Spezifikationsdatei unerwünschte Auswirkungen auf unser System haben. Lassen Sie uns rpmbuild ausführen:

rpmbuild -bb ~/rpmbuild/SPECS/feh.spec

Die Ausgabe der ausgeführten Operationen wird auf dem Bildschirm gedruckt, und wenn alles wie erwartet verläuft, wird das RPM-Paket im RPMS-Verzeichnis generiert.

Schlüsse

In diesem Tutorial haben wir die grundlegenden Konzepte kennengelernt, die bei der Erstellung eines RPM-Pakets erforderlich sind. Wir lernten einige Makros und wie man eine .spec-Datei erstellt, die alle notwendigen Anweisungen für den Erstellungsprozess enthält. Wir haben auch ein konkretes Beispiel bereitgestellt, das Erstellen und Verpacken von feh, einem einfachen Befehlszeilen-Bildbetrachter. Ich empfehle Ihnen, den offiziellen Red Hat Packaging Guide zu konsultieren, um die in diesem Tutorial erwähnten Konzepte weiter zu erweitern.

Verwandte Artikel: