RPMs bauen
Kursinhalt:
Stand: April 2006
Grundsätze
- Ein RPM enthält alle Daten und Anweisungen (%pre, %post, usw.) die nötig sind, um eine Software zu installieren.
- Konfigurieren ist nicht enthalten, eine sinnvolle Standard-Konfiguration aber gut.
- Der Prozess des Installierens und Entfernens darf wegen der automatischen Installationsverfahren nicht interaktiv sein; also keine Nutzer-Abfragen in die Anweisungen!
- Ein Source-RPM enthaelt alle Daten und Anweisungen (das Spec-File) die nötig sind, um RPMs für eine Software zu erstellen.
- Ein RPM sollte nur in absoluten Ausnahmefällen etwas enthalten, was nicht auch im zugehörigen Source-RPM ist.
- Der eigentliche Bau-Prozess sollte ausser in absoluten Ausnahmefällen nicht mit root-Rechten durchgeführt werden.
- Dazu wird mittels eines sog. Buildroot-Verzeichnisses die Installation in
%install
an irgendeinen frei zugaenglichen temporaeren Platz ausgeführt und die Files von RPM dann so eingepackt, das sie später am richtigen Ort landen.
- Dazu wird mittels eines sog. Buildroot-Verzeichnisses die Installation in
- Der Name eines Paketes besteht aus dem eigentlichen Namen, der Version und dem Release:
<name>-<version>-<release>
-
Name
,Version
undRelease
werden durch-
(Minus) getrennt, wobei zu beachten ist, dass die Zählung von rechts nach links erfolgt. Dadurch ist es möglich, auch innerhalb des Namens das Zeichen-
(Minus) zu verwenden. - Der
Name
kennzeichnet den Namen des Paketes. Dabei ist zu beachten, dass von einem Paketnamen auch immer nur ein Paket resp. eine Version bzw. Release auf einem System installiert sein kann. D.h. möchte ich 2 Versionen einer Software parallel installieren, müssen sich diese im Namen unterscheiden. - Beispiel:
-
gimp-1.2.5-2
undgimp2-2.0.1-1
-
kernel-module-openafs-2.6.9-5.0.5.ELsmp-1.3.80-1.SL.i686
undkernel-module-openafs-2.6.7-5.0.1.ELsmp-1.3.80-1.SL.i686
-
- Die
Version
korrespondiert mit der Softwareversion. - Das Release kennzeichnet die Release der Version eines Paketes. Dabei wird zwischen der Softwarerelease und der Paketierungsrelease unterscheiden. Gibt es eine Softwarerelease, so ist diese zuerst in den Releasetag einzufügen. Wird es notwendig, eine Paket der gleichen Version und Softwarerelease noch einmal zu erstellen (z.B. durch Fehler beim Paketbau), so ist an die Softwarerelease eine durch Punkt getrennte Paketierungsrelease anzuhängen und mit jedem Paketbau zu erhöhen.
- Beispiel:
-
gimp2-2.0.1-1
undgimp2-2.0.1-2
-
usbutils-0.11-6.1
undusbutils-0.11-6.2
-
- TU-Chemnitz Spezifika
- Kennzeichnung erfolgt immer mit dem Suffix
tucz
- Werden Pakete speziell für unserer Einrichtung erstellt oder umgebaut, so ist dies im Releasetag durch den Suffix
.tucz
zu kennzeichen-
print-2.6-1.tucz
-
- Werden zu existierenden Paketen Anpassungen in Form von RPM-Pakten realisiert, so ist dies im Namen durch den Suffix
_tucz
zu kennzeichen-
mozilla_tucz-1.7.7-1
-
- Kennzeichnung erfolgt immer mit dem Suffix
-
RPM-Build-Repositorys
Mittels des nun vorgestellten Verfahren ist es möglich, die bei der Erstellung von RPMs anfallenden Daten im Filesystem sauber zu strukturieren. Dazu wird mittelsrpmrepo
an beliebiger Stelle eine lokale RPM-Build-Hierarchie angelegt, darin kann dann am Paket gearbeitet und auch der Bauprozess mit rpmrbuild
angestossen werden.
Weiterhin können diese Verzeichnisse beliebig bewegt und untereinander umgeordnet werden.
Das Kommando rpmrbuild
passt die RPM-Topdir Variable automatisch an.
Tip zur Vereinfachung: Wenn man folgende Zeile in ~/.bashrc
einträgt, kann man wie gewohnt einfach rpmbuild
(ohne 'r') tippen:
alias rpmbuild='rpmrbuild'Eine RPM-Build-Hierarchie enthält folgende Unterverzeichnisse:
- SOURCE: Für die Quellen, Patches, Skripte und sonstigen Daten, die zum Bau das RPM notwendig sind.
- BUILD: Hier erfolgt die Softwaregenerierung. (Das ist ein Link ins /tmp, damit das AFS nicht bremst.)
- SPECS: Für das Spec-File.
- RPMS: Hier legt
rpmbuild
die fertigen RPMs ab; die Unterverzeichnisse (i386
,noarch
, usw.) werden automatisch angelegt. - SRPMS: Hier legt
rpmbuild
fertige Source-RPMs ab.
~/.rpmmacros
! Eigene Einstellungen können in ~/.rpmmacros.base
erfolgen, diese Datei wird an die erzeugte ~/.rpmmacros
angehängt.
Beispiel 1: Bau der Software "foobar" aus einem existierenden Source-RPM.
- repodir: Basisdirectory unter das das neue Repository gehangen wird
- srpmdir: hier liegt das alte Source-RPM
1 cd repodir 2 rpmrepo foobar 3 cd srpmdir 4 rpm -ivh foobar-1.2.3.src.rpm 5 cd repodir/foobar 6 ..... 7 cd repodir/foobar/SPECS 8 rpmrbuild -ba foobar.spec
- 2: Unterverzeichnis
foobar
wird im aktuellen Verzeichnis (repodir
) und darunter eine Hierarchie angelegt. - 4: Das Source-RPM wird in die im Schritt 2 angelegte RPM-Hierarchie installiert, nicht nach
/usr/src/redhat/
. Alternativ könnte man hier auch ein Tar-File aus dem Netz holen und im SOURCE-Verzeichnis ablegen sowie ein neues Spec-File in SPECS anlegen. - 6: Beliebige Arbeiten an Sourcen und Spec-File.
- 8: Bauprozess starten.
repodir/foobar/RPMS/...
.
Beispiel 2: Umbauten an "foobar"
1 cd repodir/foobar 2 ..... 3 cd repodir/foobar/SPECS 4 rpmrbuild -ba foobar.spec
- 2: Beliebige Arbeiten an Sourcen und Spec-File.
- 4: Bauprozess starten.
repodir/foobar/RPMS/...
.
Spec-File
- Die
Prefix:
Zeilen haben nichts mit dem Installationsort zu tun! Wenn RPM feststellt, das es fuer alle im Paket enthaltenen Files passende solche Prefix-Zeilen gibt, gilt das Paket als relokierbar. Braucht das Programm einen festen Installationsort (und das ist wohl der Normalfall), dürfen solche Zeilen nicht im Spec-File enthalten sein.
- RPM stellt eine Unmenge an Variablen zur Verfügung, z.B. enthalten
%{name}
,%{version}
und%{release}
den Inhalt der gleichnamigen Definitionszeilen.
Aufbau eines spec-Files (am unvollständigen Beispiel)
1 Summary: Calendar and Day Planner 2 Name: plan 3 Version: 1.8.7 4 Release: 6 5 License: special, see README 6 Group: Applications/Productivity 7 URL: http://www.bitrot.de/plan.html 8 Packager: Karsten Petersen <kapet@hrz.tu-chemnitz.de> 9 BuildRoot: %{_tmppath}/%{name}-%{version}-root 10 11 Source: %{name}-%{version}.tar.gz 12 Source1: netplan.conf 13 Patch0: plan-1.8.7-config.diff 14 Patch1: plan-1.8.7-togglesize.diff 15 16 %description 17 plan is a schedule planner based on X/Motif. It displays a month calendar 18 similar to xcal, but every day box is large enough ....... 19 20 %prep 21 %setup -q 22 %patch0 -p1 23 %patch1 -p1 -b .togglesize 24 25 %build 26 %configure --with-something=yes 27 make %{?_smp_mflags} 28 29 %install 30 [ -n "%{buildroot}" -a "%{buildroot}" != / ] && rm -rf %{buildroot} 31 mkdir -p %{buildroot}%{_sysconfdir} \ 32 %{buildroot}%{_datadir}/applications 33 34 make install DESTDIR=%{buildroot} 35 install -m755 %{SOURCE1} %{buildroot}%{_sysconfdir}/netplan.conf 36 37 cat > %{name}.desktop << EOF 38 [Desktop Entry] 39 Name=Plan 40 Type=Application 41 Comment=Calendar Program 42 GenericName=Calendar Program 43 Exec=/usr/bin/plan 44 Icon=plan.png 45 Terminal=0 46 EOF 47 48 desktop-file-install --vendor= \ 49 --dir=%{buildroot}%{_datadir}/applications \ 50 --add-category=X-Red-Hat-Base \ 51 --add-category=Application \ 52 --add-category=Office \ 53 %{name}.desktop 54 55 %clean 56 [ -n "%{buildroot}" -a "%{buildroot}" != / } && rm -rf %{buildroot} 57 58 %files 59 %defattr(-,root,root) 60 %doc AUTHORS ChangeLog COPYING NEWS README TODO 61 %config(noreplace) %{_sysconfdir}/netplan.conf 62 %{_bindir}/plan 63 %(_libdir)/plan/* 64 %{_datadir}/applications/%{name}.desktop 65 66 %changelog 67 * Mon Feb 20 2004 Karsten Petersen <kapet@hrz.tu-chemnitz.de> 68 - new patch xx, fixes problem ... 69 - some changes in %files 70 71 * Thu Feb 12 2004 Karsten Petersen <kapet@hrz.tu-chemnitz.de> 72 - new version 1.8.7
Header-Section
- 1: Kurzbeschreibung
- 2: Name des Paketes
- 3: Version der Software
- 4: Release des Paketes (ggf. + tucz)
- 5: Lizenz unter der die Software kommt, meist "GPL" oder "BSD"
- 6: Klassifizierung nach
/usr/share/doc/rpm-*/GROUPS
- 7: URL der Homepage der Software
- 8: wer das Paket zusammengebaut hat (also i.d.R. das Spec-File entworfen hat)
- 9: wo das Programm während des Buildprozesse hininstalliert wird, der Eintrag hier ist allgemeingültig
- [optional]
-
Requires:
-
Provides:
-
AutoProv: no
-
AutoReq: no
-
- 11-14: Quellen und Patches (müssen im SOURCE-Verzeichnis vorhanden sein, werden in das SRPM eingepackt), eine fehlende Zahl entspricht der 0 ("Source:" == "Source0:")
- 16-18: Beschreibung des Paketes
Prep-Section
bereitet das Paket zur Übersetzung vor, also Quellen in das =%{buildroot}=-Verzeichnis auspacken, Patches anwenden.- 21: Auspacken der Daten; "-q" hinter %setup unterdrückt die Ausgabe beim Auspacken des Tar-Files; Unterscheidet sich der Name des Verzeichnisses, welches beim Auspacken der Quellen entsteht von
%{name}-%{version}
, so muss der Name mit "-n" übergeben werden;%setup -n %{name}-20050512cvs
- 22-23: Anwenden von Patches; Die Nummer hinter dem Patchmacro koresspondiert mit der Nummer des Patchfiles aus der Headersection. Die OPtion "-p" wird an das Patchkommando übergeben. Soll ein Backup der gepatchten Files entstehen, so kann man das Patchmacro anweisen eine entsprechende Fileendung zu verwenden
%patch -b .test
Build-Section
Die ausgepackten und gepatchten Quellen werden übersetzt. Üblicherweise die Schritte autoconf (./configure) und make.- 26: Ist die Software für autoconf entworfen, so sollte
./configure
durch das Macro%configure
ersetzt werden. Dadurch werden dem configure korrekte Argumente für--prefix
,--bindir
,--mandir
usw. übergeben. - 27: Für make gibt es kein Macro.
%{?_smp_mflags}
ist ein Makro, welches make mitteilt, wieviele CPUs im System vorhanden sind und für den Übersetzungsprozess verwendet werden können. Das Macro jat keinen Einfluss auf das entstehende Binary.
Install-Section
Verlief der Übersetzungsprozess erfolgreich, werden die Binarys jetzt installiert. Dabei ist zu beachten, dass die Installation in ein temporäres Verzeichnis, die Buildroot erfolgt. Darunter werden die sonst in der Wurzel zu findenden Verzeichnisse wieetc
, usr/bin
, usw. aufgespannt.
Für die Verzeichnisse sollten die vordefinierten Macros verwendet werden! Siehe dazu auch /usr/lib/rpm/macros
- 30: löscht zunächst die Buildroot
- 31-32: da wir später ein Konfigfile manuell installieren wollen, legen wir schon mal eine
etc/
und ein Verzeichnis für Startmenüsymbole an. - 34: Installieren des Programmes in die Buildroot.
- 35: Das Konfigfile %{SOURCE1} wird manuell in sein Zielverzeichnis installiert.
- 37-46: Wir erstellen einen Files für das Startmenü.
- 48: und installieren dieses in die Buildroot mit dem Kommando
desktop-file-install
Clean-Section
- 56: Die Buildroot wird nach erfolgreichem Paketbau entfernt. Treten Fehler während des Paketbaues auf, wird die Cleansection nicht ausgeführt.
Scripts-Section
Die Scriptssection enthält Shellscripte, welche vor bzw, nach der Installation bzw. Deinstallation ausgeführt werden. Beachte unbedingt die Reihenfolge insbesondere beim Upgrade.-
%pre
-
%post
-
%preun
-
%postun
Files-Section
Beschreibt alle Dateien, die ins Binary-Paket sollen. Es wird bei Definition einer Buildroot automatisch dort gesucht.- 59: Standardeinstellungen für Eigentümer und Zugriffsrechte werden festgelegt
- 60: Dokumentation, aufgeführte Files und Verzeichnisse aus dem Quellpaket werden unter
/usr/share/doc/%{name}-%{version}
abgelegt - 61: Konfigurationsfiles werden mit %config gekennzeichnet. Das hat zur Folge, dass nach einer Modifikation dieser Files ein späteres Verify (rpm -V) keine Fehler (modifizierte Files) meldet. Wird die Option "(noreplace)" angegeben, so wird ein schon vorhandenes Konfigfile bei der Installation bzw. Upgrade nicht überschrieben.
- 62-64: Zum Paket gehörende Files. (Executables, Librarys, usw)
- 50-53: Dateien, die in das zusätzliche Binary-Paket sollen
Changelog-Section
- 67-72: Das Changelog enthält die Paket-Historie; es sollte erkennbar sein, wann und warum das Paket verändert wurde. Das Datum muss im Format
LANG=C date +"%a %b %d %Y"
sein.
Links
http://www.rpm.org/ http://dag.wieers.com/howto/bits/rpm-build-user.php http://dag.wieers.com/howto/rpm/ http://www-106.ibm.com/developerworks/library/l-rpm1/ http://freshrpms.net/docs/fight/ http://qa.mandrakesoft.com/twiki/bin/view/Main/RpmHowTo http://www.fedora.us/docs/spec.html GURULABS-RPM-GUIDE-v1.0.PDF: RPM-Guide (engl.)Tips und Tricks für Ausnahmefälle
Beim builden von RPMs erhalte ich die Fehlermeldung: RPM build errors: Installed (but unpackaged) file(s) found:
Das neueste RPM (ab Redhat 9) mag es nicht, wenn Dateien zwar "installiert" werden (in%install
), dann aber in der Fileliste fehlen. In dem Fall schlägt das RPM-Erstellen einfach fehl. Abhilfe bringt entweder das Anpassen des Spec-Files (fehlende Files in %install
löschen oder mit einpacken) oder ausnahmsweise (wirklich nur ausnahmsweise!) bei ganz schlimmen Fällen folgende Einstellungen in /usr/lib/rpm/macros
ändern:
#%__check_files /usr/lib/rpm/check-files %{buildroot} %_unpackaged_files_terminate_build 0 %_missing_doc_files_terminate_build 0
Was verbirgt sich in den debuginfo-RPMs?
Debuginfo-Pakete werden normalerweise bei jedem Buildprozess generiert. Darin enthalten sind unstripped (mit Debuggersymbolen) Binarys und Bibliotheken sowie die zugehörigen Quellen. Binaries sind unter /usr/lib/debug/, die Quellen unter /usr/src/debug/ zu finden. Eine coole GUI zum gdb ist dddBeim rebuilden von RPMs erhalte ich den Fehler: Could not open %files file */debugfiles.list: No such file or directory
Hier ist das extrahieren von Debuginfos aus den Binary nicht möglich oder fehlgeschlagen. Ggf. kann man verhindern, daß debuginfo-Pakete angelegt werden.%define debug_package %{nil} (im Specfile) %debug_package %{nil} (oder im ~/.rpmmacros)