Fedora-Paketbaurichtlinien
Die Paketbaurichtlinien sind eine Sammlung häufig auftretender Probleme und der ihnen beizumessenden Bedeutung. Diese Richtlinien sollten zwar nicht ignoriert, aber auch nicht blind befolgt werden. Wenn Sie der Meinung sind, dass Ihr Paket von Teilen der Richtlinien ausgenommen sein sollte, wenden Sie sich bitte an das Fedora Packaging Committee.
Diese Dokumente behandeln die Details der Erstellung akzeptabler Fedora-Pakete und enthalten zwar verschiedene Beispiele, eignen sich aber nicht besonders gut als Tutorial. Sie behandeln auch nicht die Details und Richtlinien für den Zugriff auf die Fedora-Paketquellen als Paketentwickler oder die Mechanismen zur Erstellung und Veröffentlichung von Paketen im Rahmen der Distribution. Dokumente, die diese Themen behandeln, finden Sie unter den folgenden Links:
Es liegt in der Verantwortung des Paketprüfers, auf spezifische Probleme mit einem Paket hinzuweisen, und in der Verantwortung des Paketbetreuers, diese Probleme zu beheben. Der Prüfer und der Betreuer arbeiten zusammen, um den Schweregrad der Probleme zu bestimmen (ob sie die Veröffentlichung des Pakets blockieren oder erst nach der Aufnahme des Pakets in die Paketquellen behoben werden können). Bitte beachten Sie, dass jedes von Ihnen eingereichte Paket auch den Prüfrichtlinien entsprechen muss.
Der ursprüngliche Autor dieser Dokumente ist Tom 'spot' Callaway, wobei sie ursprünglich auf vielen anderen Dokumenten basierten. Sie wurden im Laufe der Jahre von vielen Mitgliedern des Packaging Committee grundlegend überarbeitet.
Die Schlüsselwörter MUST (MUSS), MUST NOT (DARF NICHT), SHOULD (SOLLTE), SHOULD NOT (SOLLTE NICHT) und MAY (KANN) in diesen Richtlinien sind gemäß der Beschreibung inhttps://www.rfc-editor.org/rfc/rfc2119[RFC 2119] zu interpretieren.
Melden Sie Fehler in diesen Richtlinien, auch Tippfehler, bitte hier.
Anwendbarkeit
Diese Richtlinien gelten im Allgemeinen für die aktuell veröffentlichten Versionen von Fedora (jedoch NICHT für die nicht mehr unterstützten) sowie für die Entwicklungsversion von Fedora (Rawhide). Sollte ein bestimmter Abschnitt dieser Richtlinien nur für eine Untermenge dieser Versionen relevant sein, wird dies ausdrücklich vermerkt. Bitte beachten Sie jedoch, dass sich Rawhide schnell ändern kann, und es kann vorkommen, dass Änderungen dort bereits sichtbar sind, die hier noch nicht berücksichtigt wurden.
Die Richtlinien decken in gewissem Umfang auch Pakete für EPEL ab, jedoch nur in Kombination mit den EPEL-Paketbaurichtlinien. Die Fedora-Paketierung ändert sich deutlich schneller als die EPEL-Paketierung, so dass diese Richtlinien im Laufe der Zeit immer weiter von den jeweiligen EPEL-Versionen abweichen werden. Bei älteren unterstützten EPEL-Versionen können die Unterschiede daher recht erheblich sein. Abschnitte dieser Richtlinien, die nicht für EPEL gelten, werden in der Regel nicht gesondert gekennzeichnet.
Allgemeine Regel für Ausnahmen
Da diese Richtlinien niemals alle möglichen Eventualitäten abdecken können, wird es immer Pakete geben, die Ausnahmen erfordern. Es liegt in der Verantwortung des Paketbetreuers, diese Richtlinien so genau wie möglich zu befolgen und Fälle, in denen sie nicht eingehalten werden können, als Kommentare in der Spec-Datei des Pakets klar zu dokumentieren.
Wenn in einer Richtlinie die Formulierung „sollte“ oder „wird empfohlen“ verwendet wird und es für das Paket nicht möglich ist, dieser Richtlinie zu entsprechen, darf der Paketersteller davon abweichen. Die Art der Abweichung und die Begründung dafür MÜSSEN in der Spec-Datei dokumentiert werden.
Wo Formulierungen wie „muss“, „ist erforderlich“ oder „benötigt“ verwendet werden, darf der Paketersteller nur mit Genehmigung des Packaging Committee von der Richtlinie abweichen. Bitte befolgen Sie das Verfahren auf der Seite des Packaging Committee, um solche Anträge zu stellen.
Zulässige Pakete
Bitte schauen Sie sich das Dokument Was kann paketiert werden an, um sicherzustellen, dass das, was Sie paketieren wollen, in Fedora erlaubt ist.
Benennung
Schauen Sie in die Benennungsrichtlinien, um sicherzustellen, dass Ihr Paket korrekt benannt ist.
Version und Release
Eine Dokumentation zur korrekten Verwendung der Felder „Version“ und „Release“ finden Sie hier.
Lizenzierung
Sie sollten die Informationen zu den in Fedora zulässigen Lizenzen und die Lizenzierungsrichtlinien lesen, um sicherzustellen, dass Ihr Paket ordnungsgemäß lizenziert und die Lizenz korrekt angegeben ist.
Fedora-Markenzeichen
Paketersteller DÜRFEN KEINE Fedora-Markenzeichen, einschließlich des Fedora-Logos, der Fedora-Logo-Symbole oder Grafiken, die das Fedora-Logo enthalten, hinzufügen. Diese Elemente MÜSSEN dem Paket fedora-logos hinzugefügt werden. Ihre Pakete installieren die Logos, indem sie vom Paket fedora-logos abhängen. Sollte die Originalsoftware Fedora-Markenzeichen enthalten, die Ihrer Meinung nach unsachgemäß verwendet werden, wenden Sie sich bitte per E-Mail an legal@fedoraproject.org.
Dies liegt daran, dass das Fedora-Logo eine Marke ist, die einem anderen rechtlichen Rahmen unterliegt als Softwarecode. Es darf nur unter Bedingungen verbreitet werden, die die Marke schützen. Die separate Speicherung der Fedora-Marken in einem eigenen Paket anstatt deren Verteilung auf verschiedene andere Pakete ist außerdem unerlässlich, um Remixes zu ermöglichen, die notwendigerweise die Fedora-Marke nicht verwenden dürfen und stattdessen ein eigenes *-logos-Paket erstellen oder das generic-logos-Paket verwenden müssen.
Bibliotheken und Anwendungen
Viele sprach- oder domänenspezifische Richtlinien beziehen sich auf „Bibliotheken“,„Module“, „Plugins“ oder andere für die jeweilige Sprache oder Domäne spezifische Begriffe. Dies ist insbesondere für die Paketbenennung wichtig. Einige Anwendungen können Bibliotheken enthalten, und einige Bibliotheken können Anwendungen enthalten, so dass die Unterscheidung nicht immer eindeutig ist.
Blbliothek oder Anwendung?
-
Wenn der Hauptzweck eines Pakets darin besteht, ausführbare Dateien für Benutzer bereitzustellen, SOLLTE es als Anwendung paketiert werden. Enthält es zusätzlich Bibliotheken, die von anderem Code importiert oder verlinkt werden können, siehe „Gemischte Pakete“ weiter unten.
-
Wenn der Hauptzweck eines Pakets darin besteht, Bibliotheken bereitzustellen, die in anderen Code importiert oder geladen werden sollen, gilt es als Bibliothek und MUSS als solche paketiert werden. Enthält es außerdem Hilfsprogramme, die von Benutzern ausgeführt werden können, siehe „Gemischte Pakete“ weiter unten.
Es obliegt dem Paketersteller, den Hauptzweck eines Pakets festzulegen. Oftmals hat der Upstream-Entwickler dies bereits durch seine Namenswahl getan, und diese Wahl SOLLTE vom Fedora-Paketersteller übernommen werden.
Gemischte Pakete
Viele Pakete enthalten, unabhängig von ihrem Hauptzweck, sowohl Anwendungen als auch Bibliotheken. In diesem Fall SOLLTEN eine oder beide Komponenten in Teilpaketen verpackt werden, damit andere Anwendungen nur von der Bibliothek und nicht von der/den zugehörigen Anwendung(en) abhängen. Die Installation einer Anwendung, die von einer Bibliothek oder einem Dienst abhängt, sollte nicht automatisch andere Anwendungen mitinstallieren, die mit dieser Bibliothek oder diesem Dienst verknüpft sind.
Paketunabhängigkeit
Pakete SOLLTEN, sofern technisch möglich, unabhängig voneinander installierbar sein, MÜSSEN aber gegebenenfalls Abhängigkeiten des korrekten Typs zu anderen Paketen angeben (siehe Abschnitt „Abhängigkeitstypen“ weiter unten).
Desktop-Anwendungen DÜRFEN NICHT von anderen Desktop-Anwendungen abhängen, es sei denn, dass dies unbedingt erforderlich ist. Insbesondere Pakete, die eine sichtbare .desktop-Datei enthalten (eine .desktop-Datei, die nicht die Zeile NoDisplay=true enthält), sollten keine Requires-, Recommends- oder Supplements-Anweisungen für andere Pakete enthalten, die direkt oder indirekt eine sichtbare Desktop-Datei enthalten.
Es wäre beispielsweise sinnvoll, wenn ein Level-Editor für Videospiele das zugehörige Videospiel benötigt, um zu funktionieren, oder wenn ein Plugin einer Anwendung die zugehörige Anwendung benötigt. Es wäre jedoch nicht sinnvoll, wenn eine Anwendung, die zufällig eine Datenbankbibliothek verwendet, von einer Datenbankverwaltungssoftware abhängig wäre, die mit dieser Bibliothek verknüpft ist, oder wenn eine Anwendung, die zufällig eine bestimmte Programmiersprache verwendet, von Verwaltungswerkzeugen abhängig wäre, die mit dieser Programmiersprache verknüpft sind.
Wenn ein Quellpaket mehrere grafische Anwendungen bereitstellt, sollten diese Anwendungen nach Möglichkeit in separate Teilpakete ausgelagert werden.
Spec-Dateien
Die Spec-Datei („.spec“) ist ein grundlegendes Element im Paketierungsprozess.Jede Änderung am Paket führt zu einer Änderung der Spec-Datei.Da Pakete in Fedora sowohl von einer Gemeinschaft von Paketierstellern als auch von automatisierten Werkzeugen verwaltet werden, ist es wichtig, dass die Spec-Dateien bestimmten Konventionen folgen. Der Großteil dieser Richtlinien für die Paketierung betrifft den Inhalt einer Spec-Datei; hier sind einige allgemeine Punkte.
Benennung von Spec-Dateien
Sie Spec-Datei MUSS nach dem Schema %{name}.spec benannt werden. Das heißt, wenn Ihr Paket example heißt, muss die Spec-Datei example.spec heißen.
Lesbarkeit von Spec-Dateien
Alle Spezifikationsdateien MÜSSEN lesbar sein und so gepflegt werden, dass die Gemeinschaft der Paketentwickler sie verstehen und mit ihnen arbeiten kann.
Um die Lesbarkeit zu erleichtern, dürfen in Fedora-Paketen ausschließlich Makros und Bedingungsanweisungen für Fedora und EPEL verwendet werden. Die Verwendung von Makros und Bedingungsanweisungen für andere Distributionen, einschließlich Fedora-Derivaten, ist in den Spec-Dateien von Paketen in den Haupt-Fedora-Paketquellen nicht gestattet, es sei denn, diese Makros und Bedingungsanweisungen sind auch in Fedora vorhanden.
Kodierung von Spec-Dateien
Sofern Sie keine Zeichen außerhalb des ASCII-Zeichensatzes benötigen, müssen Sie sich keine Gedanken über die Kodierung der Spec-Datei machen. Falls Sie Nicht-ASCII-Zeichen benötigen, speichern Sie Ihre Spec-Dateien als UTF-8. Wenn Sie sich nicht sicher sind, welche Zeichen ASCII-Zeichen sind, konsultieren Sie bitte diese Tabelle.
Nicht-ASCII-Dateinamen
Ebenso müssen Dateinamen, die Nicht-ASCII-Zeichen enthalten, als UTF-8 kodiert werden. Da es keine Möglichkeit gibt, die Kodierung des Dateinamens zu ermitteln, ist die Verwendung derselben Kodierung für alle Dateinamen die beste Methode, um sicherzustellen, dass Benutzer die Dateinamen korrekt lesen können. Falls die upstream-seitigen Dateinamen nicht in UTF-8 kodiert sind, können Sie ein Hilfsprogramm wie convmv(1) (aus dem convmv-Paket) verwenden, um den Dateinamen in Ihrem %install-Abschnitt zu konvertieren.
Kanonizität und Pflege von Spec-Dateien
Das Git-Archiv von Fedora ist der offizielle Speicherort für Fedora-Spec-Dateien.Paketbetreuer MÜSSEN damit rechnen, dass andere Betreuer und automatisierte WerkzeugeÄnderungen an ihren Paketen vornehmen, möglicherweise ohne vorherige Kommunikation (obwohl Kommunikation stets empfohlen wird). Wenn einige Betreuerzusätzlich Kopien einer Spec-Datei in einer externen Paketquelle speichern,MÜSSEN sie bereit sein, Änderungen an der Spec-Datei in der Fedora-Paketquelle zusammenzuführen,und DÜRFEN diese Änderungen NICHT mit einer Kopie aus einer externen Paketquelleoder mit fedpkg import überschreiben.
Verifizierung von Quelldateien
Sofern das Upstream-Projekt OpenPGP-Signaturen seiner Releases veröffentlicht, sollten Fedora-Pakete diese Signatur im Rahmen des RPM-Bauprozesses verifizieren.
Obwohl eine Prüfsumme in der Quelldatei bestätigt, dass eine aus dem Lookaside-Cache abgerufene Datei diejenige ist, die der Paketersteller hochgeladen hat, gibt sie keine Auskunft darüber, ob es sich um die vom Upstream-Projekt veröffentlichte Datei handelt. Eine Signatur der Upstream-Entwickler bestätigt, dass der Quellcode mit der von ihnen veröffentlichten Version identisch ist. Die Überprüfung der Signatur im Rahmen des Bauprozesses stellt sicher, dass Paketersteller die Überprüfung nicht vergessen.
Beziehen der korrekten Schlüssel
Das Verifizierungsverfahren erfordert eine oder mehrere OpenPGP-Schlüsselbunddateien mit öffentlichen Schlüsseln des Upstream-Projekts. Die Schlüsselbünde müssen zusammen alle Schlüssel enthalten, die zur Bestätigung der Authentizität der Quellen als vertrauenswürdig gelten, und dürfen keine weiteren Schlüssel enthalten.
Idealerweise veröffentlicht das Upstream-Projekt einen solchen Schlüsselbund als herunterladbare Datei. Laden Sie diese Datei herunter und tun Sie alles Erdenkliche, um ihre Authentizität zu überprüfen. Fügen Sie sie anschließend unverändert dem Paket-SCM hinzu und geben Sie die zugehörige URL in der Spec-Datei an, damit andere sie überprüfen können. Die URL MUSS nach Möglichkeit HTTPS oder ein ähnlich authentifiziertes Protokoll verwenden.
Selbst wenn Sie den Schlüssel beim ersten Hinzufügen noch nicht verifizieren können, erhöht er dennoch die Sicherheit durch Vertrauen bei der ersten Verwendung. Er stellt sicher, dass zukünftige Angriffe erkannt werden, wenn der Schlüssel der richtige ist, oder dass ein aktueller Angriff später erkannt wird, wenn zukünftige Versionen mit dem korrekten Schlüssel signiert werden.
Verifizierung von Signaturen
Die Überprüfung der Quelldateien MUSS zuerst im Abschnitt %prep der Spec-Datei erfolgen, bevor potenziell kompromittierter Code ausgeführt wird. Die Überprüfung MUSS mit dem Makro %{gpgverify} durchgeführt werden, welches zu einem Befehl expandiert, dessen Parameter die Pfadnamen des Schlüsselbunds, der Signatur und der signierten Datei sein müssen. BuildRequires: gpgverify ist für die Durchführung der Überprüfung erforderlich.
Jede separate Signaturdatei (z. B. foo.tar.gz.asc oder foo.tar.gz.sig) musszusammen mit dem Quellcode in den Lookaside-Cache des Pakets hochgeladen werden, währendder Schlüsselbund direkt in das SCM des Pakets eingecheckt werden muss.
Das folgende Format muss verwendet werden:
Source0: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.gz
Source1: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.gz.asc
Source2: https://www.example.com/gpgkey-0123456789ABCDEF0123456789ABCDEF.gpg
…
BuildRequires: gpgverify
…
%prep
%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}'
Die erste Quelle ist das eigentliche Tarball-Archiv, die zweite die Signatur von upstream und die dritte der Schlüsselbund.
Ausnahmen
Wenn der ursprüngliche Tarball eines Pakets geändert werden muss, beispielsweise weil er unzulässige Elemente enthält, kann der Tarball nicht im Rahmen des Bauprozesses verifiziert werden. In diesem Fall muss der ursprüngliche OpenPGP-Schlüsselbund weiterhin im Paket-SCM enthalten sein, und die Anweisungen/das Skript zum Erstellen des reduzierten Tarballs müssen die ursprüngliche Quelle verifizieren.
Wenn das Upstream-Projekt keine Schlüsselbunddatei veröffentlicht (z.B. wenn esnur einen Fingerabdruck auf seiner Website veröffentlicht und auf ein Schlüsselserver-Netzwerk zum Herunterladen des Schlüssels verweist), müssen Sie möglicherweise einen Schlüsselbund erstellen, nachdem Sie den Schlüssel verifiziert haben. In diesem Fall gibt es keine Upstream-URL zum Schlüsselbund,daher sollten Sie stattdessen in einem Kommentar in der Spec-Datei dokumentieren, wie Sie den Schlüsselbund erstellt haben. Ein minimaler Schlüsselbund mit dem Schlüssel mit dem Fingerabdruck`7D33D762FD6C35130481347FDB4B54CBA4826A18` kann mit dem folgenden Befehl erstellt werden:
gpg2 --export --export-options export-minimal 7D33D762FD6C35130481347FDB4B54CBA4826A18 > gpgkey-7D33D762FD6C35130481347FDB4B54CBA4826A18.gpg
Wenn der Upstream-Anbieter einen Tarball anders signiert hat, beispielsweise nur die unkomprimierte Tarball-Version, aber dann eine komprimierte Version verteilt hat, muss der Verifizierungsschritt entsprechend angepasst werden, zum Beispiel:
Source0: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.xz
Source1: ftp://ftp.example.com/pub/foo/%{name}-%{version}.tar.asc
Source2: https://www.example.com/gpgkey-0123456789ABCDEF0123456789ABCDEF.gpg
…
BuildRequires: gpgverify xz
…
%prep
xzcat '%{SOURCE0}' | %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data=-
Wenn die Daten und die Signatur in einer einzigen Datei kombiniert werden, dann müssen die signierten Daten in eine Ausgabedatei geschrieben werden:
%{gpgverify} --keyring='%{SOURCE1}' --data='%{SOURCE0}' --output=<Pfadname>
Pakete, die für den Start von Fedora unerlässlich sind, können das Flag bootstrap flag verwenden, um die Überprüfung vor dem Kompilieren von GPGverify und GnuPG zu überspringen.
Hilfe
Wenn Sie Hilfe benötigen, um Ihr Paket an diese Richtlinie anzupassen, oder wenn Sie nicht wissen, was zu tun ist, wenn ein Bauvorgang bei der Signaturprüfung fehlschlägt, sollten Sie sich an die Fedora-Entwickler-Mailingliste wenden, bevor Sie die Prüfung umgehen, um sicherzustellen, dass Sie keine kompromittierte Software erstellen.
Unterstützung der Architekturen
Alle Fedora-Pakete müssen auf mindestens einer unterstützten primären Architektur erfolgreich kompiliert und in binäre RPM-Dateien umgewandelt werden können, außer wenn das Paket nur auf einer sekundären Architektur nützlich ist (z.B. ein architekturspezifisches Boot-Dienstprogramm, ein Microcode-Loader oder ein Hardware-Konfigurationswerkzeug). Fedora-Paketentwickler sollten sich nach Kräften bemühen, alle primären Architekturen zu unterstützen.
Inhalt, Code, der nicht kompiliert oder erstellt werden muss, und architekturunabhängiger Code (noarch) sind erwähnenswerte Ausnahmen.
Architekturbezogene Baufehler
Wenn ein Fedora-Paket auf einer bestimmten Architektur nicht kompiliert, erstellt oder ausgeführt werden kann, sollten diese Architekturen in der Spec-Datei in ExcludeArch aufgeführt werden. Für jede in ExcludeArch aufgeführte Architektur muss ein Bugzilla-Eintrag erstellt werden, der den Grund für das Kompilierungs-/Erstellungs-/Funktionsproblem des Pakets auf dieser Architektur beschreibt. Die Bugnummer sollte dann in einem Kommentar neben der entsprechenden ExcludeArch-Zeile eingefügt werden. Neue Pakete haben während des Review-Prozesses keine Bugzilla-Einträge. Daher sollten sie diese Beschreibung bis zur Genehmigung des Pakets im Kommentar einfügen und anschließend den Bugzilla-Eintrag erstellen und die ausführliche Erklärung durch die Bugnummer ersetzen. Der Bug sollte als blockierend für einen (oder mehrere) der folgenden Bugs markiert werden, um die Nachverfolgung solcher Probleme zu vereinfachen:
Noarch mit unportierten Abhängigkeiten
Manchmal arbeitet man an einem noarch-Paket, das nur dort ausgeführt werden kann, wo ein anderes, architekturabhängiges Paket aufbaut. Dies ist häufig der Fall bei Paketen, die in einer Skriptsprache geschrieben sind und beispielsweise vom Interpreterpaket der Sprache abhängen. Wenn das architekturabhängige Paket, von dem Ihr Paket abhängt, nicht auf allen Architekturen verfügbar ist, auf die Fedora (oder EPEL) abzielt, kann es vorkommen, dass Sie Ihr Paket aus den Paketquellen bestimmter Architekturen ausschließen oder verhindern müssen, dass es auf bestimmten Architekturen im Buildsystem erstellt wird.
Architekturspezifische Laufzeit- und Bauabhängigkeiten
Sie können sowohl die Architekturen, die zum Erstellen eines noarch-Pakets verwendet werden, als auch die Paketquellen, denen das erstellte noarch-Paket hinzugefügt wird, einschränken, indem Sie entweder die Tags ExcludeArch: oder ExclusiveArch: verwenden:
BuildArch: noarch
# Nachfolgend die Architekturen auflisten, auf denen das abhängige Paket aufbaut
ExclusiveArch: %{ix86} %{arm} x86_64 noarch
Manchmal stellt die Laufzeitumgebung einer Sprache, für die Sie ein Paket erstellen, ein Makro für die Architekturen bereit, auf denen sie verfügbar ist, beispielsweise %{nodejs_arches}. Falls ein solches Makro existiert, können Sie in Ihrer Spec-Datei beispielsweise ExclusiveArch: %{nodejs_arches} noarch verwenden. Schauen Sie in den Richtlinien für diese Sprache, ob ein solches Makro vorhanden ist.
Keine architekturspezifischen Quellen oder Patches
Pakete DÜRFEN KEINE Source:- oder Patch:-Tags enthalten, die von der Architektur abhängig sind. Beispielsweise ist Folgendes verboten:
%ifarch ppc64
Patch0: build-fix-for-ppc64.patch
%endif
Die bedingte Verwendung von Source:- oder Patch:-Tags anhand der Architektur führt dazu, dass sich der Inhalt des Quellpakets je nach der Architektur, die zum Erstellen verwendet wurde, unterscheidet.
Beachten Sie, dass dies leider verhindert, dass %autosetup zum Anwenden von Patches verwendet werden kann, wenn einige dieser Patches nur für bestimmte Architekturen gelten. Die beste Lösung besteht darin, Patches zu schreiben, die einfach auf allen Architekturen funktionieren. Wenn dies nicht möglich ist, verwenden Sie einfach %autosetup -N und das Makro %patch, um jeden Patch mit %ifarch oder %ifnarch anzuwenden. Zum Beispiel:
%prep
%autosetup -N
%ifarch s390x
%patch 0 -p1
%endif
Dateisystem-Layout
Fedora folgt hinsichtlich des Dateisystemlayouts dem Dateisystemhierarchie-Standard (Filesystem Hierarchie Standard, FHS) der Linux Foundation, mit den unten aufgeführten Ausnahmen. Der FHS definiert, wo Dateien im System abgelegt werden sollen.
Ausnahmen
-
Fedora erlaubt es Cross-Compilern, Dateien in
/usr/targetabzulegen. -
Das Verzeichnis der obersten Ebene
/nixdarf ausschließlich für die Nix-Laufzeitumgebung und den Paketspeicher verwendet werden. Es darf nur vom Paketnix-filesystemerstellt und verwaltet werden. -
Fedora erlaubt keine neuen Verzeichnisse direkt unter
/oder/usrohne Genehmigung des FPC.
Libexecdir
Der Dateisystemhierarchie-Standard enthält keine Vorgabe für libexecdir, aber Fedora-Pakete können dort geeignete Dateien ablegen. Libexecdir (auch bekannt als /usr/libexec auf Fedora-Systemen) sollte nur als Verzeichnis für ausführbare Programme verwendet werden, die primär für die Ausführung durch andere Programme und nicht durch Benutzer konzipiert sind.
Das RPM von Fedora enthält ein Makro für libexecdir, %{_libexecdir}. Paketerstellern wird dringend empfohlen, libexecdir-Dateien in einem paketspezifischen Unterverzeichnis von %{_libexecdir} zu speichern, z.B. %{_libexecdir}/%{name}.
Wenn die Bauskripte des Upstream-Projekts die Verwendung von %{_libexecdir} unterstützen, ist dies der geeignetste Ort für die Konfiguration (z.B. durch Übergabe von --libexecdir=%{_libexecdir}/%{name} an das configure-Skript der Autotools). Falls die Bauskripte des Upstream-Projekts dies nicht unterstützen, ist %{_libdir}/%{name} eine geeignete Alternative. Falls Sie die Unterstützung für die Verwendung eines dieser Verzeichnisse patchen müssen, sollten Sie LIBEXECDIR patchen, idealerweise konfigurierbar zur Bauzeit (damit Distributionen, die /usr/libexec nicht haben, LIBEXECDIR auf ein anderes, für ihre Distribution besser geeignetes Verzeichnis setzen können).
Für Multilib ungeeignete Orte
Wenn ein Paket von Multilib ausgenommen ist, kann es %{_prefix}/lib anstelle von %{_libdir} verwenden. Pakete, die architekturspezifische Dateien enthalten, die normalerweise in %{_libexecdir} installiert würden, gelten immer als nicht für Multilib geeignet. Sie sollten jedoch sicherstellen, dass das (Teil-)Paket, in dem sie sich befinden, keine anderen Inhalte enthält, die für Multilib geeignet wären. Wenn dies für die Dateien, die Sie für Ihr Paket verwenden möchten, nicht der Fall ist oder Sie sich einfach unsicher sind, wenden Sie sich bitte an FESCo, um eine explizite Ausnahme von Multilib zu beantragen.
/run
Systemdienste sollten kleine, flüchtige Laufzeitdaten in /run speichern. Dies ist ein tmpfs-basiertes Verzeichnis, das sehr früh beim Systemstart eingebunden wird, bevor Dienste gestartet werden (und bevor /var verfügbar ist). /var/run ist ein veralteter symbolischer Link auf /run.
Keine Dateien oder Verzeichnisse unter /srv, /usr/local oder /home/$USER
Der Dateisystemhierarchie-Standard besagt:
„… no program should rely on a specific subdirectory structure of /srv existing or data necessarily being stored in /srv. However /srv should always exist on FHS compliant systems and should be used as the default location for such data.“ (Kein Programm sollte sich auf eine bestimmte Unterverzeichnisstruktur von /srv verlassen oder darauf, dass Daten notwendigerweise in /srv gespeichert sind. /srv sollte jedoch auf FHS-konformen Systemen immer vorhanden sein und als Standardspeicherort für solche Daten verwendet werden.) Die Distributionen müssen darauf achten, dass lokal abgelegte Dateien in diesen Verzeichnissen nicht ohne Administratorrechte gelöscht werden.
Der Dateisystemhierarchie-Standard übergibt die Kontrolle über die Verzeichnisstruktur unter /srv explizit dem Systemadministrator und nicht der Distribution. Daher können Fedora-Pakete keine Dateien oder Verzeichnisse unter /srv enthalten, vorkonfiguriert sein, um bestimmte Dateien oder Verzeichnisse unter /srv zu verwenden, Dateien dort zu entfernen oder die Dateien dort in irgendeiner Weise zu verändern.
Darüber hinaus darf kein Fedora-Paket unter folgenden Verzeichnissen Dateien oder Verzeichnisse enthalten oder Dateien verändern:
-
/usr/local, da die Verwendung dieser Verzeichnisse durch die Distributionen gemäß dem Dateisystemhierarchie-Standard nicht gestattet ist. -
/home/$USER, da Benutzer die Dateien in ihren Home-Verzeichnissen beliebig ändern können, und RPM-Pakete, die diese Dateien verändern, das Risiko bergen, Benutzerdaten zu zerstören. Darüber hinaus können Websites/homeauf verschiedenen Systemen per NFS einbinden oder es bei Bedarf im Netzwerk automatisch einbinden. Die Änderung von Dateien in so konfigurierten Home-Verzeichnissen hat in beiden Fällen negative Auswirkungen.
Es ist wichtig zu beachten, dass die Software in einem Fedora-Paket, sobald sie installiert und vom Benutzer konfiguriert wurde, /srv als Datenspeicherort verwenden kann. Das Paket darf dies jedoch nicht standardmäßig tun.
Eingeschränkte Verwendung von /opt, /etc/opt und /var/opt
Das Verzeichnis /opt und die zugehörigen Verzeichnisse (/etc/opt und /var/opt) sind im Dateisystemhierarchie-Standard für die Verwendung durch Anbieter reserviert. Wir haben den Namen fedora mit LANANA für unsere Verwendung reserviert. Wenn ein Paket Dateien in /opt installiert, darf es nur Verzeichnisse in der Hierarchie /opt/fedora verwenden. Fedora versucht, dieses Verzeichnis zu organisieren, indem für bestimmte Subsysteme ein Unterverzeichnis von /opt/fedora zugewiesen wird. Wenn Sie der Meinung sind, dass Sie /opt/fedora verwenden müssen, erstellen Sie bitte ein Ticket beim Fedora Performance Center (FPC), damit entschieden werden kann, ob die Verwendung von /opt zulässig ist und welches Unterverzeichnis für Sie zugewiesen werden soll.
Gegenwärtig haben wir /opt/fedora/scls, /etc/opt/fedora/scls und /var/opt/fedora/scls für die Software Collections zu Nutzung zugewiesen.
Die von Google bereitgestellte Chrome-Paketierung hat einen bestimmten Speicherort für erweiterungsspezifische Dateien gewählt. Dieser steht, falls verwendet, mit den oben genannten Richtlinien in Konflikt. Daher hat das Packaging Committee die folgende Ausnahme genehmigt: Ein Paket KANN Dateien im Verzeichnis /etc/opt/chrome/native-messaging-hosts installieren und diese Verzeichnishierarchie erstellen, solange das Paket als Ganzes auch Chromium unterstützt. (Die Chromium-Unterstützung KANN in einem separaten Teilpaket enthalten sein.) Sollte Chrome in Zukunft die Verwendung eines gängigeren Verzeichnisses für diesen Zweck zulassen, wird diese Ausnahme entfernt.
Zusammengeführtes Dateisystem-Layout
Fedora hat verschiedene Verzeichnisse zusammengeführt, die historisch gesehen voneinander getrennt waren.
| Pfad | Zusammengeführt mit | RPM-Makro |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Beispielsweise werden Endbenutzer feststellen, dass /bin/sh die gleiche Datei ist wie /usr/bin/sh, und dass /usr/sbin/sendmail die gleiche Datei ist wie /usr/bin/sendmail.
Die Abhängigkeiten von RPM-Dateien richten sich jedoch nicht nach dem Inhalt des Dateisystems, sondern nach dem im Abschnitt %files der RPM-Konfiguration angegebenen Pfad. Ein RPM-Paket, das Folgendes angibt:
%files
/bin/sh
könnte eine Dateiabhängigkeit für /bin/sh erfüllen, nicht aber für /usr/bin/sh. Pakete müssen die tatsächlichen Dateisystempfade im Abschnitt %files verwenden. Falls andere Pakete von einem anderen Pfad abhängen, der auf dieselbe Datei verweist, und es nicht praktikabel ist, diese auf den neuen Pfad zu aktualisieren, dürfen Pakete ein virtuelles Provides verwenden, um den alternativen Pfad aufzulisten.
Zum Beispiel:
Provides: /sbin/ifconfig
[...]
%files
%{_bindir}/ifconfig
rpmlint verwenden
Führen Sie rpmlint auf Binär- und Source-RPMs aus, um sie auf häufige Fehler zu untersuchen und zu beheben (sofern rpmlint nicht fehlerhaft ist, was ebenfalls vorkommen kann). Falls die Ausgabe von rpmlint kryptisch erscheint, können Sie mit dem Schalter -e ausführlichere Beschreibungen der meisten Fehler und Warnungen erhalten. Beachten Sie, dass rpmlint zusätzliche Prüfungen durchführt, wenn der Name eines installierten Pakets angegeben wird. Beispielsweise führt dnf install foo-1.0-1.f20.x86_64.rpm; rpmlint -i foo eine Reihe von Tests für das Paket foo durch, die rpmlint foo-1.0-1.f20.x86_64.rpm nicht durchführen kann. Eine von der Community gepflegte Seite zu rpmlint-Problemen finden Sie hier.
Tags und Abschnitte
-
Die Tags
Copyright:,Packager:,Vendor:undPreReq:DÜRFEN NICHT verwendet werden. -
Die Tags
BuildRoot:,Group:und der Abschnitt%cleanSOLLTEN NICHT verwendet werden. -
Der Inhalt von Buildroot SOLLTE NICHT in der ersten Zeile von
%installentfernt werden. -
Der Tag
Summary:SOLLTE NICHT mit einem Punkt enden. -
Die
Source:-Tags dokumentieren, wo die Upstream-Quellen für das Paket zu finden sind. In den meisten Fällen SOLLTE dies eine vollständige URL zum Upstream-Tarball sein. Für Sonderfälle beachten Sie bitte die SourceURL-Richtlinien. -
URLs in den Tags
URL:,Source:undPatch:SOLLTEN nach Möglichkeit eine Serverauthentifizierung erfordern. Dies bedeutet in der Regel, dass manhttps:anstelle vonhttp:oderftp:verwendet.
Paketabhängigkeiten
Alle Paketabhängigkeiten (BAU- oder Laufzeitabhängigkeiten, reguläre, weiche oder sonstige) MÜSSEN IMMER innerhalb der offiziellen Fedora-Paketquellen erfüllt werden können.
RPM kann Abhängigkeiten für die meisten kompilierten Bibliotheken und für einige Skriptsprachen wie Perl automatisch ermitteln. Automatisch ermittelte Abhängigkeiten DÜRFEN NICHT durch manuelle Abhängigkeiten dupliziert werden.
Bauabhängigkeiten MÜSSEN jedoch explizit aufgeführt werden, es sei denn, Sie verwenden einen automatischen Bauabhängigkeitsgenerator (z.B. Rust oder Python). Siehe Bauabhängigkeiten (BuildRequires).
Versionierte Abhängigkeiten (zur Bauzeit oder Laufzeit) SOLLTEN NUR dann verwendet werden, wenn sie tatsächlich notwendig sind, um sicherzustellen, dass die richtige Version eines Pakets vorhanden ist. Wenn eine versionierte Abhängigkeit durch eine Version erfüllt werden könnte, die in drei vorherigen Fedora-Versionen vorhanden war, ist eine versionierte Abhängigkeit nicht erforderlich und stattdessen SOLLTE eine reguläre, nicht versionierte Abhängigkeit verwendet werden.
Eine versionierte Abhängigkeit von einem Paket mit definierter Epoche MUSS in dieser Abhängigkeit enthalten sein. Andernfalls wird die Abhängigkeit nicht wie erwartet funktionieren.
Abhängigkeitstypen
Requires MUSS verwendet werden, wenn die Abhängigkeit für die korrekte Funktion der Software erforderlich ist.
Funktioniert das Paket zwar korrekt, aber mit eingeschränkter Funktionalität, dannSOLLTEN Recommends oder Suggests verwendet werden. Soll die Funktionalität standardmäßig für Benutzer verfügbar sein, SOLLTE Recommends verwendet werden, andernfalls Suggests. Alternativ können die umgekehrten Abhängigkeiten Supplements oder`Enhances` im anderen Paket verwendet werden. SiehePackaging:WeakDependencies für Richtlinien zur Verwendung dieser Abhängigkeitstypen.
Architekturspezifische Abhängigkeiten
Eine Abhängigkeit wird architekturspezifisch angegeben, indem das Makro %{?_isa} an den Paketnamen angehängt wird. Zum Beispiel:
Requires: foo
wird zu:
Requires: foo%{?_isa}
Wenn das Paket foo-devel ein Skript foo-config enthält, können Sie versuchen, foo-config --libs und foo-config --cflags auszuführen, um konkrete Hinweise darauf zu erhalten, welche Pakete als Abhängigkeiten für foo markiert werden sollten. Zum Beispiel:
$ gtk-config --cflags -I/usr/include/gtk-1.2 -I/usr/include/glib-1.2 -I/usr/lib/glib/include -I/usr/X11R6/include $ gtk-config --libs -L/usr/lib -L/usr/X11R6/lib -lgtk -lgdk -rdynamic -lgmodule -lglib -ldl -lXi -lXext -lX11 -lm
Das bedeutet, dass gtk+-devel Folgendes enthalten sollte:
Requires: glib-devel%{?_isa} libXi-devel%{?_isa} libXext-devel%{?_isa} libX11-devel%{?_isa}
Rich/Boolean-Abhängigkeiten
Pakete KÖNNEN die in RPM unterstützte Funktion für erweiterte (oder boolesche) Abhängigkeiten vollständig nutzen.
Datei- und Verzeichnisabhängigkeiten
RPM ermöglicht es Ihnen, von beliebigen Dateien oder Verzeichnissen anstelle von Paketen abhängig zu sein.Pakete KÖNNEN solche Abhängigkeiten für Pfade innerhalb eines der folgenden Verzeichnisse enthalten:
-
/usr/bin -
/etc
Sie KÖNNEN auch von Pfaden abhängen, die in einem expliziten Provides: aufgeführt sind. Sie DÜRFEN keine Abhängigkeiten von anderen Pfaden enthalten, da dies das Herunterladen vonzusätzlichen Paketquellen-Metadaten erfordern würde.
Bitte beachten Sie außerdem, dass es nicht ungewöhnlich ist, dass mehrere Pakete dasselbe Verzeichnis bereitstellen. Verzeichnisabhängigkeiten SOLLTEN NUR verwendet werden, um die Abhängigkeit vom Vorhandensein dieses Verzeichnisses auszudrücken, nicht von anderen Funktionen anderer Pakete, die dieses Verzeichnis möglicherweise bereitstellen.
Bei der Deklaration von Datei- und Verzeichnisabhängigkeiten dürfen RPMMacros.adoc#macros_installation[Installationspfad-Makros] wie %{_bindir} nicht verwendet werden. Der Wert von %{_bindir} des Pakets, das sometool bereitstellt, kann sich von dem Wert von %{_bindir} eines Pakets unterscheiden, das sometool benötigt. In diesem Fall funktioniert BuildRequires: %{_bindir}/sometool nicht wie erwartet.
Explizite Abhängigkeiten
Explizite Abhängigkeiten (Requires) sind jene, die vom Paketersteller manuell in der Spec-Datei hinzugefügt werden. Pakete dürfen keine unnötigen expliziten Abhängigkeiten für Bibliotheken enthalten. Wir verlassen uns im Allgemeinen auf rpmbuild, um Abhängigkeiten von Bibliotheks-SONAMEs automatisch hinzuzufügen. Moderne Paketverwaltungswerkzeuge können solche Abhängigkeiten in vielen Fällen auflösen, um die benötigten Pakete zu ermitteln. Allerdings fügen aktuelle Versionen von rpmbuild nur Abhängigkeiten von Bibliotheks-SONAMEs hinzu, nicht von der vollständigen Bibliotheksversion. Dies kann problematisch sein, wenn eine Bibliothek im Laufe der Zeit Funktionen hinzugefügt hat, ohne dass Abwärtsinkompatibilitäten bestehen, die eine Änderung der SONAMES erforderlich machen würden. Dies kann dazu führen, dass der Benutzer eine alte Version einer Bibliothek installiert hat, die neue Version der Bibliothek mit neuer ABI in Fedora erstellt wird und eine Anwendung, die diese ABI verwendet, erstellt wird. Wenn der Benutzer versucht, nur diese eine Anwendung zu installieren oder zu aktualisieren, ohne gleichzeitig die Bibliothek zu aktualisieren, lässt sich die Anwendung zwar zunächst problemlos installieren (da die SONAME-Abhängigkeit erfüllt ist), schlägt aber beim Ausführen fehl, weil der auf dem System installierten Bibliothek die benötigten Funktionen fehlen.
Obwohl Sie explizite Bibliotheksabhängigkeiten hinzufügen müssen, um dies zu verhindern, hat die manuelle Angabe in allen Ihren Paketen Nachteile. Erfahrungsgemäß führen solche Abhängigkeiten zu Verwirrung, wenn Bibliotheken/Dateien von einem Paket in ein anderes verschoben werden, Pakete umbenannt werden, eines von mehreren alternativen Paketen ausreicht oder versionierte explizite Abhängigkeiten veraltet und ungenau werden. Darüber hinaus erfordern alte explizite Abhängigkeiten von Paketnamen in manchen Fällen unnötige Aktualisierungen/Neuerstellungen. Beispielsweise müssen Fedora-Pakete nur für zwei vollständige Veröffentlichungszyklen historische Abhängigkeiten beibehalten.
Aus diesem Grund und weil wir hoffen, dies in rpmbuild zu beheben, ist dies etwas, was Sie beachten sollten.Es ist jedoch nicht erforderlich, die benötigten Bibliotheken mit ihren Versionsinformationen explizit anzugeben.
Wenn explizite Bibliotheksabhängigkeiten erforderlich sind, sollten diese typischerweise architekturspezifisch sein (es sei denn, die beteiligten Pakete sind architekturunabhängig). Außerdem sollte ein Kommentar in der Spec-Datei dies begründen:
# The automatic dependency on libfubar.so.1 is insufficient,
# as we strictly need at least the release that fixes two segfaults.
Requires: libfubar%{?_isa} >= 0:1.2.3-7
Paketersteller sollten explizite Abhängigkeiten gegebenenfalls überprüfen, um zu vermeiden, dass sie ungenau und überflüssig werden. Im obigen Beispiel ist es beispielsweise nicht mehr notwendig, die explizite Versionsangabe aufzulisten, wenn keine aktuelle Fedora-Version mit libfubar < 1.2.3-7 ausgeliefert wird.
Filterung automatisch ermittelter Abhängigkeiten
RPM versucht, während des Bauprozesses automatisch Abhängigkeiten (Requires) und Bereitstellungen (Provides) zu generieren. In manchen Fällen sind diese jedoch nicht korrekt oder unerwünscht. Weitere Informationen zum Filtern automatisch generierter Requires und Provides finden Sie hier: Packaging:AutoProvidesAndRequiresFiltering.
Bauabhängigkeiten (BuildRequires)
Es ist wichtig, dass Ihr Paket alle notwendigen Bauabhängigkeiten mithilfe des Tags BuildRequires: auflistet. Sie KÖNNEN davon ausgehen, dass eine ausreichende Umgebung für die Funktion von RPM, das Erstellen von Paketen und das Ausführen einfacher Shell-Skripte vorhanden ist, aber Sie SOLLTEN NICHT davon ausgehen, dass andere Pakete als RPM-Abhängigkeiten vorhanden sind, da sich alles, was vom Build-System in das Build-Verzeichnis gebracht wird, im Laufe der Zeit ändern kann.
BuildRequires und %{_isa}
Sie DÜRFEN KEINE BuildRequires mit Architekturangaben verwenden. Die Architektur landet im erstellten SRPM. SRPMs müssen jedoch architekturunabhängig sein. Wenn Sie beispielsweise Folgendes tun:
# Beispiel, was man *nicht* tun sollte
BuildRequires: foo%{?_isa} >= 3.3
Dann hätte das in Fedora erstellte SRPM eine der folgenden Abhängigkeiten, abhängig davon, mit welchem Builder das SRPM erstellt wurde:
foo(x86-32) >= 3.3 # oder foo(x86-64) >= 3.3
Dies würde verhindern, dass yum-builddep oder ähnliche Werkzeuge, die die SRPM-Abhängigkeiten verwenden, korrekt funktionieren.
BuildRequires basierend auf pkg-config
Fedora-Pakete, die pkg-config verwenden, um gegen eine Bibliothek (z.B. 'foo') zu kompilieren, von der sie abhängen, SOLLTEN ihre Bauabhängigkeit korrekt als pkgconfig(foo) angeben. Weitere Informationen finden Sie unter Packaging:PkgConfigBuildRequires.
Bedingte Bauabhängigkeiten
Wenn die Spec-Datei bedingte Abhängigkeiten enthält, die basierend auf dem Vorhandensein optionaler --with(out) foo-Argumente für rpmbuild ausgewählt wurden, wird das Source-RPM mit den Standardoptionen erstellt, das heißt, so dass keines dieser Argumente in der Befehlszeile von rpmbuild vorhanden ist. Der Grund dafür ist, dass diese Abhängigkeiten in das resultierende Source-RPM „serialisiert“ werden, das heißt, die Bedingungen gelten dann nicht mehr.
Zusammenfassung und Beschreibung
Die Zusammenfassung (Summary) sollte eine kurze und prägnante Beschreibung des Pakets sein. Die Beschreibung (Description) sollte dies weiter ausführen.
Gebote und Verbote
-
Setzen Sie am Ende der Zusammenfassung (Summary) keinen Punkt.
-
Die Zusammenfassung sollte maximal 80 Zeichen/Spalten umfassen. Falls Sie einen anderen Zeichensatz als ASCII verwenden, nutzen Sie eine UTF-Längenfunktion oder eine ähnliche Methode, um die Spaltenanzahl zu berechnen.
-
Stellen Sie sicher, dass die Beschreibung keine Zeilen enthält, die länger als 80 Zeichen/Spalten sind. Wenn Sie einen anderen Zeichensatz als ASCII verwenden, nutzen Sie eine UTF-Längenfunktion oder eine ähnliche Funktion, um die Spaltenanzahl zu berechnen.
-
Fügen Sie keine Installationsanweisungen in die Beschreibung ein; es handelt sich nicht um ein Handbuch. Falls das Paket eine manuelle Konfiguration erfordert oder andere wichtige Anweisungen für den Benutzer enthält, verweisen Sie den Benutzer auf die Dokumentation im Paket. Fügen Sie eine README.Fedora oder ähnliche Datei hinzu, falls Sie dies für notwendig halten.
-
Aus Gründen der Einheitlichkeit verwenden wir in der Zusammenfassung und Beschreibung die Rechtschreib- und Grammatikregeln des amerikanischen Englisch. Pakete können, sofern verfügbar, zusätzliche übersetzte Zusammenfassungen/Beschreibungen für unterstützte nicht-englische Sprachen enthalten.
Markenzeichen in Zusammenfassung oder Beschreibung
Paketersteller sollten beim Umgang mit Marken in Zusammenfassung oder Beschreibung vorsichtig sein. Es gibt einige Regeln zu beachten:
-
Verwenden Sie niemals
(TM)oder(R)(oder die Unicode-Entsprechungen ™/®). Die korrekte Verwendung dieser Zeichen ist äußerst kompliziert, daher ist es tatsächlich sicherer, sie gar nicht zu verwenden. -
Markenrechte sollten eindeutig verwendet werden. Vermeiden Sie Formulierungen wie „ähnlich wie“ oder „wie“. Beispiele:
-
SCHLECHT: It is similar to Adobe Photoshop.
-
GUT: It supports Adobe Photoshop PSD files, …
-
SCHLECHT: A Linux version of Microsoft Office
-
GUT: A word-processor with support for Microsoft Office DOC files
Wenn Sie sich nicht sicher sind, fragen Sie sich: Besteht die Möglichkeit, dass jemand das Paket mit dr Software mit diesem Markenzeichen verwechselt? Im Zweifelsfall sollten Sie das Markenzeichen gar nicht erwähnen.
Dokumentation
Jegliche relevante Dokumentation, die in der Quelldistribution enthalten ist, sollte im entsprechenden Dokumentationsverzeichnis des Pakets abgelegt werden. Nicht relevante Dokumentation umfasst Bauanweisungen, die allgegenwärtige Datei INSTALL mit allgemeinen Bauanweisungen oder Beispielen sowie Dokumentation für Nicht-Linux-Systeme, z.B. README.MSDOS. Achten Sie außerdem darauf, in welches Teilpaket Sie die Dokumentation einfügen. Die API-Dokumentation beispielsweise gehört in das Teilpaket -devel, nicht in das Hauptpaket. Bei umfangreichen Dokumentationen empfiehlt es sich, sie in ein eigenes Teilpaket auszulagern. In diesem Fall wird empfohlen, *-doc als Namen für das Teilpaket zu verwenden.
Die Kennzeichnung eines relativen Pfades mit %doc im Abschnitt %files bewirkt, dass RPM die referenzierte Datei oder das Verzeichnis von %_builddir an den korrekten Speicherort für die Dokumentation kopiert. Dateien können auch in %_pkgdocdir abgelegt werden, und die Bauskripte der zu paketiernden Software können dies automatisch tun, wenn sie in %install aufgerufen werden. Die Kombination dieser Methoden ist jedoch problematisch und kann zu doppelten oder in Konflikt stehenden Dateien führen. Daher ist die Verwendung von %doc mit relativen Pfaden und die direkte Installation von Dateien in %_pkgdocdir im selben Quellpaket nicht zulässig.
Als Dokumentation gekennzeichnete Dateien dürfen nicht dazu führen, dass das Paket mehr Abhängigkeiten einbindet, als es ohne die Dokumentation der Fall wäre. Eine einfache Möglichkeit, dies in den meisten Fällen sicherzustellen, besteht darin, alle Ausführungsberechtigungen für Dateien im Verzeichnis %_pkgdocdir zu entfernen.
Dateien im Verzeichnis %_pkgdocdir dürfen die paketierte Software zur Laufzeit nicht beeinflussen. Die Software muss auch dann einwandfrei und mit unveränderter Funktionalität arbeiten, wenn diese Dateien geändert, entfernt oder gar nicht erst installiert werden.
Obwohl Lizenzdateien Dokumentationen darstellen, werden sie speziell behandelt(unter anderem durch die Verwendung eines anderen Tags). In den Lizenzierungsrichtlinien lesen Sie, wie Sie damit umgehen.
Separate Dokumentationspakete
Wenn die Erstellung der Dokumentation viele zusätzliche Abhängigkeiten erfordert, können Sie entscheiden, diese nicht im Hauptpaket zu erstellen, sondern ein separates *-doc-Quellpaket zu erstellen, das nur die Dokumentation enthält. Diese separat paketierte Dokumentation muss der Version der paketierten Software entsprechen. Mit anderen Worten: Wenn eine neue Version der Software Änderungen an der Dokumentation enthält, muss auch das Dokumentationspaket aktualisiert werden. Enthält die neue Version der Software jedoch keine Änderungen an der Dokumentation, können Sie entscheiden, das Dokumentationspaket nicht zu aktualisieren.
Ein Kommentar SOLLTE zum Versions-Tag des Hauptpakets hinzugefügt werden, um die Paketbetreuer daran zu erinnern, das separate *-doc-Paket bei Bedarf zu aktualisieren.
Changelogs
Das Änderungsprotokoll (Changelog) beschreibt die Änderungen am Paket, die für die Benutzer relevant sind. Dies umfasst neue Upstream-Versionen, wichtige Änderungen am Bauprozess, Rebuilds und andere Änderungen, die das Ergebnis beeinflussen. Änderungen, die nur für Paketersteller relevant sind, sollten nicht im Änderungsprotokoll erwähnt werden. Dazu gehören Bereinigungen von Spec-Dateien, Fehlerbehebungen oder Workarounds für Baufehler sowie andere Änderungen, die keinen Einfluss auf den Inhalt der Binärpakete haben.
Das Änderungsprotokoll sollte automatisch aus den Git-Commit-Protokollen mit Hilfe des Makros %autochangelog generiert werden:
%changelog
%autochangelog
Der Betreff des Commits (die erste Zeile der Commit-Nachricht) und optional einige zusätzliche Zeilen werden verwendet, um den Changelog-Text zu generieren. Der Name und die E-Mail-Adresse des Commit-Autors sowie der Commit-Zeitstempel werden ebenfalls im Changelog-Eintrag verwendet.
Der Text der Commit-Nachricht, die Teil des Änderungsprotokolls wird, sollte eine kurze Zusammenfassung der für den Benutzer relevanten Änderungen enthalten. Die Commit-Nachricht kann auch zusätzliche Informationen enthalten, die für Paketersteller relevant sind.
Wenn eine bestimmte Änderung mit einem Bugzilla-Fehlerbericht zusammenhängt, fügen Sie die Bug-ID zur einfacheren Referenz in den Änderungsprotokolleintrag ein, z.B.
Add README file (rhbz#1000042)
Wenn ein bestimmter Commit eine CVE behebt, sollten diese Informationen ebenfalls angegeben werden.
Ziel ist es, dem Benutzer einen Hinweis auf die Änderungen in einer Paketaktualisierung zu geben, ohne ihn mit technischen Details zu überfordern. Die Einträge dürfen niemals einfach eine vollständige Kopie der CHANGELOG-Einträge des Quellcodes enthalten. Links zu den entsprechenden NEWS-Dateien oder Changelogs können für diejenigen hinzugefügt werden, die zusätzliche Informationen wünschen.
In der https://fedora-infra.github.io/rpmautospec-docs/autochangelog.html [Autochangelog-Dokumentation] finden Sie Details zur Generierung des Changelogs aus Git-Commit-Nachrichten und zur Erstellung mehrzeiliger Einträge oder zum Überspringen von Einträgen für bestimmte Commits.
Paketierer können alternativ ein manuelles Änderungsprotokoll anstelle des Makros %autochangelog verwenden. Die Vorgehensweise wird hier beschrieben.
Beispiel
Der Paketersteller aktualisiert ein Paket auf Version 1.0 und erzeugt einen Commit
$ git show
commit 0000000000001234567890ABCDEF000000000000
Author: Joe Packager <joe@example.com>
Date: Wed Jun 14 2003
Version 1.0
... (rhbz#1000024)
- Also fixes the slowdown reported in rhbz#1000025
- Upstream changelog: https://example.com/package/NEWS.html#v1.0
Whitespace in the spec file has been cleaned up.
diff --git package.spec package.spec
index 5c77064c03..efcd53a61c 100644
--- package.spec
+++ package.spec
@@ -1,5 +1,5 @@
Name: package
-Version: 0.1
+Version: 0.2
Release: %autorelease
...
Beim Bauen des Pakets wird ein entsprechender Eintrag im Änderungsprotokoll generiert. Dieser kann mit rpmautospec generate-changelog in der Vorschau angezeigt werden:
$ rpmautospec generate-changelog * Wed Jun 14 2003 Joe Packager <joe@example.com> - 0.2-1 - Version 1.0 (rhbz#1000024) - Also fixes the slowdown reported in rhbz#1000025 - Upstream changelog: https://example.com/package/NEWS.html#v1.0
Beachten Sie, dass der Satz zum Leerraum („whitespace“) nicht in das Änderungsprotokoll aufgenommen wird.
Handbuchseiten
Da Unix-Handbuchseiten (Manpages) die traditionelle Methode sind, um Hilfe auf einem Unix-System zu erhalten, sollten Pakete sie für alle ausführbaren Dateien enthalten. Falls Manpages fehlen, sollten die Paketersteller mit dem Upstream-Projekt zusammenarbeiten, um diese hinzuzufügen. Gelegentlich findet man auch Manpages anderer Distributionen oder kann die Ausgabe des Programms help2man verwenden; diese sind oft ein nützlicher Ausgangspunkt. Beachten Sie bei der Installation von Manpages, dass RPM sie in sein bevorzugtes Format komprimiert. Daher muss der Abschnitt %files die Manpages mit einem Muster referenzieren, das dies berücksichtigt:
%files
%{_mandir}/man1/foo.1*
Beachten Sie außerdem, dass Dateien, die in %{_mandir} installiert sind, von RPM automatisch als Dokumentation gekennzeichnet werden. Daher ist die Verwendung von %doc nicht erforderlich.
Für lokalisierte Manpages verwenden Sie %find_lang --with-man, wie in Umgang mit Locale-Dateien beschrieben.
Compiler
Fedora-Pakete sollten standardmäßig gcc als Compiler verwenden (für alle von gcc unterstützten Sprachen) oder clang, falls die Upstream-Software das Kompilieren mit gcc nicht unterstützt. Aus technischen Gründen können sich Paketersteller jedoch entscheiden, nicht den Standard-Compiler zu verwenden. Beispiele für solche Gründe sind unter anderem:
-
Der Standard-Compiler kann ein Paket nicht korrekt bauen.
-
Der Paketersteller muss eine Compilerfunktion (z. B. LTO) deaktivieren, damit der Standardcompiler sein Paket korrekt kompilieren kann.
-
Der Standardcompiler benötigt deutlich länger, um ein Paket zu bauen.
-
Dem Standardcompiler fehlt ein Funktionsmerkmal, von dem das Paket profitieren würde.
Paketersteller, die einen nicht standardmäßigen Compiler verwenden, sollten den Grund für diese Entscheidung in einem Kommentar in der Spec-Datei dokumentieren.
Compiler-Makros
Wenn Clang zum Erstellen eines Pakets verwendet wird, müssen Paketersteller das Makro %toolchain auf „clang“ setzen:
%global toolchain clang
Dies stellt sicher, dass beim Kompilieren die Clang-spezifischen Compiler-Flags von Fedora verwendet werden.
Wenn ein Paketersteller bedingte Makros in einer Spec-Datei verwenden möchte, um den Wechsel zwischen zwei verschiedenen Compilern zu vereinfachen, sollten die folgenden Makronamen verwendet werden:
%bcond_with toolchain_clang
%bcond_with toolchain_gcc
Paketersteller können anstelle der festen Angabe des Compilernamens auch die Makros %build_cc, %build_cxx oder %build_cpp in der Spec-Datei verwenden. Die Werte dieser Variablen werden durch Setzen des Makros %toolchain auf „clang“ oder „gcc“ gesteuert.
Compiler-Flags
Compiler, die zum Bauen von Paketen verwendet werden, müssen die entsprechenden Compiler-Flags berücksichtigen, die in der System-RPM-Konfiguration festgelegt sind. Dies bedeutet, dass der Inhalt dieser Variable als Grundlage für die Flags dient, die der Compiler während des Paketbaus tatsächlich verwendet.
Für C-, C++- und Fortran-Code enthält das %{optflags}-Makro diese Flags. Das Außerkraftsetzen dieser Flags zur Leistungsoptimierung (z.B. -O3 statt -O2) wird generell nicht empfohlen. Sollten Sie Benchmarks vorlegen können, die eine signifikante Beschleunigung für diesen speziellen Code belegen, kann dies im Einzelfall erneut geprüft werden. Das Hinzufügen, Außerkraftsetzen oder Filtern von Teilen dieser Flags ist zulässig, sofern ein triftiger Grund dafür vorliegt; die Begründung hierfür muss in der Spec-Datei dokumentiert werden.
Pakete SOLLTEN die manuelle Bearbeitung der Umgebungsvariablen 'CFLAGS' usw. vermeiden und stattdessen die in der Dokumentation hier beschriebenen Methoden zur Manipulation von Compiler-Flags verwenden.
Es gibt bestimmte sicherheitsrelevante Flags, die allgemein zulässig sind. Diese Flags können die Performance geringfügig beeinträchtigen, aber die erhöhte Sicherheit kann sich für manche Programme lohnen.
PIE
PIE erhöht die Sicherheit von ausführbaren Dateien, indem es diese vollständig aus positionunabhängigem Code (PIC) zusammensetzt. Positionunabhängiger Code (PIC) ist Maschinenbefehlscode, der unabhängig von seiner Speicheradresse korrekt ausgeführt wird. PIE ermöglicht es Exec Shield, die Adressraum-Layout-Randomisierung zu nutzen, um zu verhindern, dass Angreifer während eines Sicherheitsangriffs, der auf der Kenntnis des Offsets des ausführbaren Codes in der Binärdatei basiert (z.B. Return-to-libc-Angriffe), den Standort des vorhandenen ausführbaren Codes ermitteln können.
In Fedora ist PIE standardmäßig aktiviert. Um es in Ihrer Spec-Datei zu deaktivieren, fügen Sie Folgendes hinzu:
%undefine _hardened_build
Wenn Ihr Paket eines der folgenden Kriterien erfüllt, DÜRFEN Sie die PIE-Compiler-Flags NICHT deaktivieren:
-
Ihr Paket läuft lange. Das bedeutet, dass es wahrscheinlich gestartet wird und so lange läuft, bis der Rechner neu gestartet wird, und nicht bei Bedarf startet und sich im Leerlauf beendet.
-
Ihr Paket enthält SUID-Binärdateien oder Binärdateien mit Capabilities.
-
Ihr Paket wird mit Root-Rechten ausgeführt.
Debuginfo-Pakete
Pakete sollten nützliche -debuginfo-Pakete erzeugen oder diese explizit deaktivieren, wenn dies nicht möglich ist, rpmbuild dies aber trotzdem tun würde. Wenn ein -debuginfo-Paket explizit deaktiviert wird, ist eine Erklärung dafür in der Spec-Datei erforderlich. Debuginfo-Pakete werden in einem separaten Dokument ausführlicher beschrieben: Packaging:Debuginfo.
Devel-Pakete
Fedora-Pakete müssen logisch nach Dateistruktur aufgebaut sein.Insbesondere müssen -devel-Pakete Dateien enthalten, dieausschließlich für die Entwicklung bestimmt sind oder nur zur Bauzeit benötigt werden. Dies dient dazu,den Installationsaufwand für Benutzer zu minimieren. Es gibt einige Dateitypen,die fast immer in ein -devel-Paket gehören:
-
Headerdateien (foo.h), die sich üblicherweise in /usr/include befinden
-
Statische Bibliotheksdateien, wenn das Paket keine passenden gemeinsam genutzten Bibliotheksdateien bereitstellt. Weitere Informationen zu diesem Szenario finden Sie unter Paketieren statischer Bibliotheken.
-
Nicht versionierte, gemeinsam genutzte Systembibliotheksdateien, wenn eine passende versionierte, gemeinsam genutzte Systembibliotheksdatei ebenfalls vorhanden ist. Zum Beispiel, wenn Ihr Paket Folgendes enthält:
/usr/lib/libfoo.so.3.0.0 /usr/lib/libfoo.so.3 /usr/lib/libfoo.so
Die versionierten gemeinsam genutzten Bibliotheksdateien (/usr/lib/libfoo.so.3.2.0 und /usr/lib/libfoo.so.3) sind erforderlich, damit Benutzer Programme ausführen können, die mit libfoo verknüpft sind. Daher gehören sie in das Basispaket. Die andere, nicht versionierte gemeinsam genutzte Bibliotheksdatei (/usr/lib/libfoo.so) wird nur verwendet, um libfoo mit dem zu kompilierenden Code zu verknüpfen, und muss nicht auf dem System des Benutzers installiert sein. Das bedeutet, dass sie in ein -devel-Paket gehört. Bitte beachten Sie, dass in den meisten Fällen nur die vollständig versionierte gemeinsam genutzte Bibliotheksdatei (/usr/lib/libfoo.so.3.2.0) eine tatsächliche Datei ist; alle anderen Dateien sind symbolische Links darauf. Wenn eine gemeinsam genutzte Bibliotheksdatei nur in einem nicht versionierten Format bereitgestellt wird, sollte der Paketersteller die Upstream-Entwickler bitten, die Bereitstellung einer ordnungsgemäß versionierten Bibliotheksdatei in Betracht zu ziehen. Wenn die gemeinsam genutzte Bibliotheksdatei jedoch für die Ausführung von Programmen, die damit verknüpft sind, erforderlich ist, muss sie in das Basispaket aufgenommen werden. Falls die gemeinsam genutzte Bibliotheksdatei später von einem Upstream-Projekt versioniert wird, müssen die Paketbetreuer darauf achten, auf das oben beschriebene Versionsschema umzustellen.
Unversionierte gemeinsam genutzte Objekte
Als zusätzliche Komplikation erzeugt manche Software Dateien wie unversionierte gemeinsam genutzte Objekte, die nicht als Systembibliotheken verwendet werden sollen. Diese Dateien sind üblicherweise Plugins oder modulare Funktionen, die spezifisch für eine Anwendung bestimmt sind und nicht in den ld-Bibliothekspfaden oder im Zwischenspeicher abgelegt werden dürfen. Diese Art von unversionierten gemeinsam genutzten Objekten muss nicht in ein -devel-Paket aufgenommen werden. Sie werden erst zur Laufzeit geladen und sollten in einem privaten Verzeichnis des Hauptpakets abgelegt werden.
Detaillierte Informationen und eine ausführliche Anleitung zum Umgang mit diesen DSO-Typen finden Sie hier.
Ausnahmen
Es gibt einige erwähnenswerte Ausnahmen von diesem Paketierungsmodell, insbesondere:
-
Compiler integrieren häufig Entwicklungsdateien in das Hauptpaket, da Compiler selbst ausschließlich für die Softwareentwicklung verwendet werden und ein aufgeteiltes Paketmodell daher keinen Sinn ergibt.
Im Zweifelsfall, ob eine Datei ins Basispaket oder ins -devel-Paket gehört, sollten Paketersteller prüfen, ob die Datei für die korrekte Nutzung oder Ausführung der Funktionen im Basispaket erforderlich ist oder ob sie nur für die Entwicklung benötigt wird. Ist sie nur für die Entwicklung erforderlich, muss sie in ein -devel-Paket verschoben werden.
Wie bei allen Fedora-Paketierungsrichtlinien ist uns bewusst, dass esSonderfälle gibt, die außerhalb dieses Modells liegen. Sollten Sie auf einen solchen Fall stoßen, erstellen Sie bitte ein Ticket beim Fedora Packaging Committee und beschreiben Sie ihn uns, damit wir die Richtlinien entsprechend erweitern können.
Pkgconfig-Dateien (foo.pc)
Die Platzierung von pkgconfig(.pc)-Dateien hängt von ihrem Anwendungsfall ab. Da sie fast immer für Entwicklungszwecke verwendet werden, sollten sie in einem -devel-Paket abgelegt werden. Eine sinnvolle Ausnahme besteht, wenn das Hauptpaket selbst ein Entwicklungswerkzeug ist, das nicht in einer Benutzerlaufzeitumgebung installiert ist, z.B. gcc oder gdb.
Abhängigkeit vom Basispaket
Teilpakete sind oft Erweiterungen ihres Basispakets und sollten in diesem Fall ihr Basispaket benötigen. Wenn ein Teilpaket das Basispaket benötigt, muss es dies über eine vollständig versionierte, architekturspezifische Abhängigkeit (für Nicht-noarch-Pakete) tun:
Requires: %{name}%{?_isa} = %{version}-%{release}
Devel-Pakete sind ein Beispiel für Pakete, die ihre Basispakete über eine vollständig versionierte Abhängigkeit benötigen. -libs-Teilpakete, die nur gemeinsam genutzte Bibliotheken enthalten, müssen normalerweise nicht explizit von ihren Basispaketen abhängen, da sie diese in der Regel nicht für die Funktionalität ihrer Bibliotheken benötigen.
Wenn Sie in eine Situation geraten, in der das Hauptpaket vom Teilpaket abhängt,und das Teilpaket wiederum vom Hauptpaket, sollten Sie sorgfältig darüber nachdenken, warumnicht einfach alles im Hauptpaket enthalten ist.
Gemeinsam genutzte Bibliotheken
Wann immer möglich (und praktikabel), SOLLTEN Fedora-Pakete, die Bibliotheken enthalten, diese als gemeinsam genutzte Bibliotheken erstellen. Es ist nicht notwendig, ldconfig beim Installieren gemeinsam genutzter Bibliotheken aufzurufen.
Auflisten gemeinsam genutzter Bibliotheksdateien
Gemeinsam genutzte Bibliotheken, die direkt in %{_libdir} installiert sind, SOLLTEN NICHT im Abschnitt %files der Spec-Datei mithilfe eines Glob-Musters aufgeführt werden, das wichtige Teile des Dateinamens (z.B. libfoo.so*) verschleiert, da Änderungen am „SONAME“ in den meisten Fällen auch zu einer Änderung des Dateinamens führen.
Anderenfalls, wenn die Bibliothek im Rahmen einer Aktualisierung ihre SONAME-Datei aktualisiert, könnte diese Änderung unbemerkt bleiben und Probleme wie fehlerhafte Abhängigkeiten verursachen (weitere Informationen finden Sie im entsprechenden Abschnitt Updates Policy).
Wenn die Verwendung von Glob-Mustern jedoch vom Paketersteller als sinnvoll erachtet wird – beispielsweise, wenn sich die Teile „Y“ und „Z“ einer Bibliothek namens „libfoo.so.X.Y.Z“ häufig ändern –, empfiehlt sich stattdessen die Verwendung von etwas wie „libfoo.so.X{,.*}“, da abhängige Pakete bei solchen Änderungen in der Regel nicht neu gebaut werden müssen.
Downstream-seitige .so-Name-Versionierung
Falls das Upstream-Projekt eine unversionierte .so-Bibliothek ausliefert (die also nicht für Plugins, Treiber usw. benötigt wird), muss der Paketersteller unbedingt versuchen, das Upstream-Projekt davon zu überzeugen, mit der Versionierung zu beginnen.
Falls dies aufgrund mangelnder Bereitschaft oder fehlender Reaktion des Upstream-Projekts fehlschlägt, kann der Paketersteller zwar mit der Versionierung im Downstream-Projekt beginnen, dies muss jedoch mit Vorsicht und idealerweise nur in seltenen Fällen geschehen. Wir möchten keine Bibliothek erstellen, die mit Upstream-Projekten in Konflikt geraten könnte, falls diese später versionierte Shared Libraries bereitstellen. Die unversionierte Bibliothek darf unter keinen Umständen in Fedora ausgeliefert werden.
Für die Downstream-Versionierung sollte der Name folgendermaßen zusammengesetzt sein:
libfoobar.so.0.n
Der Wert für n sollte anfänglich eine kleine Ganzahl sein (z.B. „1“). Wir verwenden hier zwei Ziffern („0,n“), da es bei Upstream-Projekten üblich ist, hier nur eine einzelne Ziffer zu verwenden. Die Verwendung mehrerer Ziffern hilft uns, potenzielle zukünftige Konflikte zu vermeiden. Vergessen Sie nicht, das Feld SONAME (siehe unten) zur Bibliothek hinzuzufügen.
Bei der Veröffentlichung neuer Versionen der Bibliothek sollten Sie ein ABI comparison tool verwenden, um die ABI-Unterschiede in den erstellten gemeinsam genutzten Bibliotheken zu überprüfen. Falls Inkompatibilitäten festgestellt werden, erhöhen Sie den Wert von n um 1.
SONAME-Behandlung
Beim Aufrufen einer ausführbaren Datei, die mit einem gemeinsam genutzten Objekt mit SONAME-Feld verknüpft ist, prüft der dynamische Linker dieses Feld anstelle des Dateinamens, um das Objekt zu bestimmen, gegen das gelinkt werden soll. Dadurch können Entwickler einfach mit dem nicht versionierten Bibliotheks-Symlink linken, und der dynamische Linker linkt dann mit dem richtigen Objekt.
Beachten Sie, dass der Dateiname zwar üblicherweise aus dem SONAME der Bibliothek und einer fortlaufenden Unterversionsnummer besteht, aber keine intrinsische Verknüpfung zwischen diesen beiden Elementen besteht. ldconfig verwendet den SONAME als Wert für einen symbolischen Link zum eigentlichen Dateinamen. Der dynamische Linker verwendet diesen symbolischen Link dann, um die Bibliothek zu finden, und ignoriert dabei den eigentlichen Dateinamen. Der dynamische Linker führt lediglich eine einfache Gleichheitsprüfung des Feldes durch und prüft nicht auf ABI-Inkompatibilitäten oder ähnliche Probleme. Dies ist der Hauptgrund für die Verwendung eines ABI comparison tool und die Erhöhung des SONAME.
Das Feld SONAME wird vom Linker mithilfe der Flags -soname SONAME (zumindest im Fall von ld) in das gemeinsam genutzte Objekt geschrieben. Dies kann wie folgt als Option an gcc übergeben werden:
$ gcc $CFLAGS -Wl,-soname,libfoo.so.0.n -o libfoo.so.0.n
Um zu prüfen, ob das Feld SONAME gesetzt ist und welchen Wert es hat, verwenden Sie den Befehl objdump (aus binutils):
$ objdump -p /pfad/zu/libfoo.so.0.n | grep 'SONAME'
Paketieren statischer Bibliotheken
Pakete, die Bibliotheken enthalten, SOLLTEN statische Bibliotheken so weit wie möglich ausschließen (z. B. durch Konfiguration mit --disable-static). Anwendungen, die gegen Bibliotheken gelinkt sind, SOLLTEN dynamische Bibliotheken und nicht statische Versionen verwenden.
Libtool-Archive (Dateien mit der Endung foo.la) SOLLTEN NICHT eingebunden werden. Pakete, die libtool verwenden, installieren diese standardmäßig, selbst wenn Sie mit --disable-static konfigurieren. Daher müssen sie möglicherweise vor dem Paketieren entfernt werden. Aufgrund von Fehlern in älteren Versionen von libtool oder in Programmen, die libtool verwenden, kann es vorkommen, dass *.la-Dateien nicht ohne Programmänderungen entfernt werden können. In den meisten Fällen ist es jedoch recht einfach, diese Probleme in Zusammenarbeit mit den Upstream-Entwicklern zu beheben. Beachten Sie: Wenn Sie eine Bibliothek in einer stabilen Version (nicht Entwicklungsversion) aktualisieren und das Paket bereits *.la-Dateien enthält, SOLLTE das Entfernen der *.la-Dateien als API-/ABI-Änderung behandelt werden. — Das heißt, ihre Entfernung verändert die Schnittstelle, die die Bibliothek dem „Rest der Welt“ bietet. Daher MÜSSEN die Fedora-Richtlinien für potenziell destabilisierende Aktualisierungen befolgt werden.
Paketieren statischer Bibliotheken
-
Generell SOLLTEN Paketierer keine statischen Bibliotheken ausliefern.
-
Wir möchten nachverfolgen können, welche Pakete statische Bibliotheken verwenden (um beispielsweise feststellen zu können, welche Pakete neu gebaut werden müssen, wenn eine Sicherheitslücke in einer statischen Bibliothek behoben wird). Es gibt zwei Szenarien, in denen statische Bibliotheken paketiert werden:
-
Statische und dynamische Bibliotheken. In diesem Fall MÜSSEN die statischen Bibliotheken in einem Teilpaket *-static abgelegt werden. Durch die Trennung der statischen Bibliotheken von den anderen Entwicklungsdateien in *-devel können wir deren Verwendung nachverfolgen, indem wir prüfen, welche Pakete das Paket *-static als `BuildRequire`verwenden. Ziel ist es, dass Pakete nach Möglichkeit von der Verwendung dieser statischen Bibliotheken auf die Verwendung der dynamischen Bibliotheken umsteigen. Wenn das Teilpaket *-static Header oder andere Dateien aus *-devel benötigt, um verwendet werden zu können, MUSS es das Teilpaket *-devel einbinden.
-
Nur statische Bibliotheken. Wenn ein Paket ausschließlich statische Bibliotheken bereitstellt, können Sie alle statischen Bibliotheksdateien im Teilpaket *-devel ablegen. In diesem Fall benötigen Sie außerdem ein virtuelles „Provide:“ für das Paket *-static:
%package devel Provides: foo-static = %{version}-%{release}
-
Pakete, die explizit gegen die statische Version verlinken müssen, MÜSSEN BuildRequire: foo-static verwenden, damit die Verwendung nachverfolgt werden kann.
-
Wenn ein Paket gemeinsam genutzte Bibliotheken enthält (und nur genau dann), die statische Bibliotheken für ihre Funktion benötigen, können die statischen Bibliotheken in das Teilpaket *-devel eingebunden werden. Das Teilpaket -devel muss eine virtuelle Bereitstellung für das Paket *-static besitzen, und Pakete, die davon abhängen, müssen das Paket *-static mit
BuildRequireeinbinden.
Paketierung von reinen Header-Bibliotheken
Bestimmte Bibliotheken, insbesondere einige C++-Template-Bibliotheken, sind reine Header-Bibliotheken. Da der Code zur Kompilierzeit generiert wird, verhalten sie sich wie statische Bibliotheken und müssen auch so behandelt werden.
Platzieren Sie alle Header-Dateien im Teilpaket *-devel. Anschließend benötigen Sie eine virtuelle Bereitstellung für das Paket *-static:
%package devel
Provides: foo-static = %{version}-%{release}
Für Pakete, die die Header-Bibliothek verwenden, muss BuildRequire: foo-static angegeben werden, damit die Verwendung nachverfolgt werden kann.
Verwendung von noarch in Teilpaketen
Das Basispaket einer Header-Bibliothek darf nicht als „noarch“ gekennzeichnet sein. Dadurch wird sichergestellt, dass alle Tests auf allen Architekturen ausgeführt werden und es ermöglicht, festzustellen, ob der Bau- oder Installationsprozess die Header basierend auf der Architektur, für die gebaut wird, verändert hat.
Wenn die Inhalte von Teilpaketen, einschließlich des Pakets -devel, tatsächlich architekturunabhängig sind, können sie dennoch als „noarch“ gekennzeichnet sein. Da das Basispaket einer Header-Bibliothek typischerweise keine %files-Liste besitzt, kann dies zu einem architekturabhängigen Paket führen, das ausschließlich noarch-RPMs erstellt. Dies kann das Hinzufügen von %global debug_package %{nil} zur Spec-Datei erfordern, um Probleme mit leeren debugsourcefiles.list-Dateien zu vermeiden.
Statisches Linken ausführbarer Dateien
Ausführbare Dateien und Bibliotheken SOLLTEN NICHT statisch gegen Bibliotheken gelinkt werden, die aus anderen Paketen stammen. (Es ist natürlich zulässig, Dateien, die während des Bauprozesses eines Pakets generiert wurden, statisch mit .a-Dateien zu verknüpfen, die ebenfalls im Rahmen dieses Bauprozesses generiert wurden.)
Falls es notwendig ist, gegen .a-Dateien aus einem anderen Paket zu linken, muss eine Bauabhängigkeit vom -static-Paket (nicht nur vom -devel-Paket), das diese Dateien bereitstellt, vorhanden sein, damit die Verwendung nachverfolgt werden kann.
Bündelung und Duplizierung von Systembibliotheken
Fedora-Pakete SOLLTEN alles daransetzen, zu vermeiden, dass mehrere separate Upstream-Projekte in einem einzigen Paket zusammengefasst werden.
Alle Pakete, deren Upstream-Projekte die Verwendung von Systembibliotheken erlauben, MÜSSEN mit Systembibliotheken kompiliert werden. In diesem Fall MÜSSEN die mitgelieferten Bibliotheken (und/oder deren Quellcode) während %prep explizit gelöscht werden. Die Bauskripte müssen möglicherweise angepasst werden, um diese Situation zu berücksichtigen. Wenn möglich, sollte der Patch die Verwendung der mitgelieferten Bibliotheken bedingt festlegen, damit er zur Prüfung an den Upstream-Entwickler weitergeleitet werden kann.
Alle Pakete, deren Upstream-Projekte keinen Mechanismus zum Kompilieren gegen Systembibliotheken besitzen, KÖNNEN optional gebündelte Bibliotheken bereitstellen. In diesem Fall MÜSSEN sie jedoch angeben, welche Bibliotheken gebündelt sind. Dies ermöglicht es, Bibliotheken mit gebündeltem Code zu finden, was beispielsweise dabei helfen kann, Pakete mit potenziellen Sicherheitslücken zu identifizieren.
Um einen Fall von Bibliotheksbündelung zu identifizieren, ermitteln Sie zunächst den Namen und die Version der gebündelten Bibliothek:
-
Falls das gebündelte Paket auch separat in der Distribution vorhanden ist, verwenden Sie den Namen dieses Pakets. Andernfalls konsultieren Sie die Benennungsrichtlinien, um einen geeigneten Namen für die Bibliothek zu ermitteln, so als ob sie als separates Paket in die Distribution aufgenommen werden würde.
-
Ziehen Sie die Versionsrichtlinien zu Rate, um eine geeignete Version für die Bibliothek zu ermitteln, falls möglich. Falls die Bibliothek von einem Upstream-Projekt abgeleitet wurde, verwenden Sie die Upstream-Version, die zuletzt übernommen oder auf die zuletzt ein Rebase durchgeführt wurde, oder die Version, die die ursprüngliche Bibliothek zum Zeitpunkt der Ableitung hatte.
Fügen Sie dann an einer geeigneten Stelle in Ihrer Spec-Datei Provides: bundled(<Bibliotheksname>)= <Version> hinzu, wobei <Bibliotheksname> und <Version> der Name und die Version sind, die Sie oben ermittelt haben. Falls keine Version ermittelt werden konnte, verwenden Sie stattdessen`Provides: bundled(<Bibliotheksname>)`.
Zusätzlich zur Kennzeichnung der Bündelung auf diese Weise müssen Pakete, deren Upstream-Entwickler keinen Mechanismus zum Kompilieren mit Systembibliotheken besitzen, öffentlich kontaktiert werden, um einen Weg zur Unterstützung von Systembibliotheken zu finden. Falls sich die Upstream-Entwickler weigern, muss dies in der Spec-Datei vermerkt werden, entweder in Kommentaren neben dem obigen Abschnitt Provides: oder in einer zusätzlichen Datei, die in das SCM eingecheckt und durch einen Kommentar neben dem obigen Abschnitt Provides: referenziert wird.
Bündelung von Schriften in anderen Paketen vermeiden
Schriften in allgemeinen Formaten wie Type1, OpenType TT (TTF) oder OpenType CFF (OTF) unterliegen spezifischen Paketierungsrichtlinien (siehe FontsPolicy.adoc[Packaging/FontsPolicy]) und sollten stets in den systemweiten Schriftenverzeichnissen und nicht in privaten Anwendungsverzeichnissen abgelegt werden. Weitere Informationen finden Sie unter FontsPolicy.adoc[Packaging/FontsPolicy].
Vorsicht vor rpath
Manchmal werden beim Linken von Binärdateien bestimmte Bibliothekspfade fest kodiert (mithilfe des Schalters -rpath oder -R). Dies wird üblicherweise als rpath bezeichnet. Normalerweise lösen der dynamische Linker und Loader (ld.so) die Abhängigkeiten der ausführbaren Datei von gemeinsam genutzten Bibliotheken auf und laden die benötigten. Wird jedoch -rpath oder -R verwendet, werden die Pfadinformationen fest in die Binärdatei codiert und von ld.so zu Beginn der Ausführung geprüft. Da der dynamische Linker von Linux in der Regel intelligenter ist als ein fest kodierter Pfad, erlauben wir die Verwendung von rpath in Fedora normalerweise nicht.
Es gibt ein Tool namens check-rpaths, das im Paket rpmdevtools enthalten ist. Es empfiehlt sich, es dem Makro %__arch_install_post in Ihrer Konfigurationsdatei ~/.rpmmacros hinzuzufügen:
%__arch_install_post \
/usr/lib/rpm/check-rpaths \
/usr/lib/rpm/check-buildroot
Wenn check-rpaths ausgeführt wird, könnte die Ausgabe beispielsweise so aussehen:
ERROR 0001: file '/usr/bin/xapian-tcpsrv' contains a standard rpath '/usr/lib64' in [/usr/lib64]
Jeder durch check-rpaths festgestellte rpath MUSS entfernt werden.
rpath für interne Bibliotheken
Wenn ein Programm interne Bibliotheken installiert, werden diese oft nicht im Systempfad abgelegt. Diese internen Bibliotheken werden nur für die Programme verwendet, die im Paket enthalten sind (z.B. um Code auszulagern, der in den ausführbaren Dateien enthalten ist). Diese Bibliotheken sind nicht für die Verwendung außerhalb des Pakets vorgesehen. In diesem Fall ist es zulässig, dass die Programme innerhalb des Pakets einen RPATH verwenden, um diese Bibliotheken zu finden.
Beispiel:
# Internal libraries for myapp are present in:
%{_libdir}/myapp/
%{_libdir}/myapp/libmyapp.so.0.3.4
%{_libdir}/myapp/libmyapp.so
# myapp has an rpath to %{_libdir}/myapp/
readelf -d /usr/bin/myapp | grep RPATH
0x0000000f (RPATH) Library rpath: [/usr/lib/myapp]
Nicht-interne Bibliotheken: Wenn Programme außerhalb des Pakets
gegen die Bibliothek verlinken sollen,
ist es besser, die
Alternative to Rpath zu verwenden
oder die Bibliotheken einfach nach %{_libdir} zu verschieben.
Dadurch kann der dynamische Linker die Bibliotheken finden,
ohne dass alle Programme mit einem RPATH verlinkt werden müssen.
|
Alternativen zu rpath
Oft wird rpath verwendet, weil eine Binärdatei nach Bibliotheken an einem nicht standardmäßigen Ort sucht (Standardorte sind /lib, /usr/lib, /lib64, /usr/lib64). Wenn Sie eine Bibliothek an einem nicht standardmäßigen Ort speichern (z. B. /usr/lib/foo/), sollten Sie eine benutzerdefinierte Konfigurationsdatei in /etc/ld.so.conf.d/ erstellen. Wenn beispielsweise 32-Bit-Bibliotheken von libfoo in /usr/lib/foo abgelegt werden würden, würde eine Datei namens „foo32.conf“ in /etc/ld.so.conf.d/ erstellt werden, die Folgendes enthält:
/usr/lib/foo
Stellen Sie sicher, dass Sie auch eine 64-Bit-Version dieser Datei erstellen (z.B. foo64.conf), es sei denn, das Paket ist für 64-Bit-Architekturen deaktiviert.
rpath entfernen
Es gibt mehrere verschiedene Möglichkeiten, das rpath-Problem zu beheben:
-
Wenn die Anwendung ein „configure“-Skript verwendet, versuchen Sie, das Flag --disable-rpath an „configure“ zu übergeben.
-
Wenn die Anwendung eine lokale Kopie von libtool verwendet, fügen Sie die folgenden Zeilen nach %configure zur Spec-Datei hinzu:
%configure
sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
-
Manchmal kann der Code bzw. die Makefiles so angepasst werden, dass die Flags
-rpathoder-Rnicht mehr aufgerufen werden. Dies ist jedoch nicht immer einfach oder sinnvoll. -
Als letzten Ausweg bietet Fedora das Paket chrpath an. Nach der Installation dieses Pakets können Sie
chrpath --deleteauf die Dateien anwenden, die RPATHs enthalten. In unserem vorherigen Beispiel würden wir also Folgendes ausführen:
chrpath --delete $RPM_BUILD_ROOT%{_bindir}/xapian-tcpsrv
Vergessen Sie nicht, BuildRequires: chrpath hinzuzufügen, falls Sie diese Methode verwenden.
Konfigurationsdateien
Konfigurationsdateien müssen in Paketen als solche gekennzeichnet werden.
Als Faustregel gilt: Verwenden Sie %config(noreplace) anstelle von %config, es sei denn, Sie sind sich sicher, dass dies zu Problemen führen wird. Anders ausgedrückt: Überlegen Sie gut, bevor Sie lokale Änderungen in Konfigurationsdateien bei Paketaktualisierungen überschreiben. Ein Beispiel, wann Sie noreplace nicht verwenden sollten, ist, wenn sich die Konfigurationsdatei eines Pakets so ändert, dass die neue Paketrevision nicht zur Konfigurationsdatei der vorherigen Paketrevision kompatibel ist. Wenn Sie %config verwenden, fügen Sie der Spec-Datei einen kurzen Kommentar hinzu, der den Grund dafür erläutert.
Verwenden Sie unter /usr nicht %config oder %config(noreplace). /usr enthält in Fedora keine Konfigurationsdateien.
Konfiguration von Paketverwaltungswerkzeugen
Pakete DÜRFEN KEINE Paketquellen-Konfigurationsdateien installieren, die gegen die Richtlinie für Drittanbieter-Paketquellen verstoßen, es sei denn, diese Dateien werden unter %{_docdir} installiert.
Produktbezogene Konfiguration
In der Fedora.next-Welt bieten wir eine Auswahl kuratierter Fedora-Produkte sowie die klassische Fedora-Version an. Bisher haben wir für alle Fedora-Installationen einheitliche Standardkonfigurationen verwendet. Für unterschiedliche Anwendungsfälle ergeben sich jedoch unterschiedliche Anforderungen. Informationen zur Erstellung von Paketen, die sich in verschiedenen Fedora.next-Produkten unterschiedlich verhalten sollen, finden Sie in den Richtlinien zur produktspezifischen Konfiguration.
Init-Skripte
In Fedora sind Init-Skripte im SystemV-Stil nicht erlaubt. Stattdessen müssen Systemd-Units verwendet werden.
Systemd-Units
Detaillierte Richtlinien für das Paketieren von Systemd-Units und systemd-verwalteten Diensten finden Sie hier.
Desktop-Dateien
Enthält ein Paket eine GUI-Anwendung, muss es auch eine korrekt installierte .desktop-Datei enthalten. Im Sinne dieser Richtlinien ist eine GUI-Anwendung jede Anwendung, die ein Fenster zeichnet und innerhalb dieses Fensters ausgeführt wird. Installierte .desktop-Dateien MÜSSEN den Standards desktop-entry-spec entsprechen. Dabei ist insbesondere auf die korrekte Verwendung der Einträge Name, GenericName, Categories und StartupNotify zu achten.
Icon-Eintrag in Desktop-Dateien
Der Icon-Eintrag kann auf zwei verschiedene Arten angegeben werden:
-
Vollständiger Pfad zu einer spezifischen Symboldatei:
Icon=/usr/share/pixmaps/comical.png
-
Kurzer Name ohne Dateiendung:
Icon=comical
Der Kurzname ohne Dateiendung wird bevorzugt, da er die Verwendung von Symbolen ermöglicht (standardmäßig wird .png angenommen, dann .svg und schließlich .xpm versucht), aber beide Methoden sind akzeptabel.
Erstellung einer .desktop-Datei
Falls das Paket keine eigene .desktop-Datei enthält und installiert, müssen Sie eine eigene erstellen. Dies können Sie tun, indem Sie eine von Ihnen erstellte .desktop-Datei als Quelle einbinden (z.B. Source3: %{name}.desktop) oder sie in der Spec-Datei erzeugen. Hier ist der Inhalt einer beispielhaften .desktop-Datei (comical.desktop):
[Desktop Entry] Name=Comical GenericName=Comic Archive Reader Comment=Open .cbr & .cbz files Exec=comical Icon=comical Terminal=false Type=Application Categories=Graphics;
Vewendung von desktop-file-install
Es genügt nicht, die .desktop-Datei einfach in das Paket aufzunehmen. Sie MÜSSEN desktop-file-install (in %install) ODER desktop-file-validate (in %check oder %install) ausführen und BuildRequires: desktop-file-utils angeben, um die Sicherheit der .desktop-Datei und die Einhaltung der Spec-Datei-Vorschriften zu gewährleisten. desktop-file-install MUSS verwendet werden, wenn das Paket die Datei nicht installiert oder Änderungen an der .desktop-Datei gewünscht sind (z.B. Hinzufügen/Entfernen von Kategorien usw.). desktop-file-validate KANN stattdessen verwendet werden, wenn der Inhalt/Speicherort der .desktop-Datei nicht geändert werden muss. Hier sind einige Anwendungsbeispiele:
desktop-file-install \
--dir=%{buildroot}%{_datadir}/applications \
%{SOURCE3}
desktop-file-install \
--add-category="AudioVideo" \
--delete-original \
--dir=%{buildroot}%{_datadir}/applications \
%{buildroot}/%{_datadir}/applications/foo.desktop
desktop-file-validate %{buildroot}/%{_datadir}/applications/foo.desktop
Weisen Sie .desktop-Dateien keinen Vendor-Tag zu (mittels --vendor).
AppData-Dateien
Pakete mit grafischen Anwendungen sollten AppData-Dateien enthalten. SiehePackaging:AppData für die entsprechenden Richtlinien.
Makros
Paketerstellern wird dringend empfohlen, Makros anstelle von fest kodierten Verzeichnisnamen zu verwenden (siehe RPM-Makros). In Fällen, in denen das Makro länger als der zugehörige Pfad ist oder in denen der Paketersteller die Verwendung des eigentlichen Pfads als übersichtlicher empfindet, ist es ihm jedoch gestattet, den eigentlichen Pfad anstelle des Makros zu verwenden. Es gibt einige Einschränkungen bei diesem Vorgehen:
-
Das Paket muss konsistent sein. Verwenden Sie für jeden Pfad innerhalb derselben Spec-Datei entweder einen fest kodierten Pfad oder ein Makro, nicht eine Kombination aus beidem.
-
%{_libdir} muss aufgrund der Multi-Lib-Architektur immer für Binärbibliotheken verwendet werden; ein ersatzweise fest kodierter Pfad ist nicht zulässig.
Makros, deren Namen mit Unterstrichen beginnen, gelten im Allgemeinen alsinterne Implementierungsdetails für RPM und die zugehörigen Makropakete undSOLLTEN in Spec-Dateien NICHT referenziert werden, außer um ihre Werte festzulegen, um das Verhalten von RPM zu beeinflussen. Dies bedeutet, dass Makroformen von SystemprogrammenNICHT verwendet werden SOLLTEN. Beispielsweise sollte rm anstelle von %{__rm} verwendet werden. In manchen Fällen sind die benötigten Daten jedoch unter Namen ohne vorangestellte Unterstriche nicht verfügbar. In diesem Fall KANN das Makro mit vorangestellten Unterstrichen verwendet werden. Autoren von Makropaketenwird empfohlen, bei der Benennung von Makros, die in Spec-Dateien verwendet (und nicht festgelegt) werden sollen, auf vorangestellte Unterstriche zu verzichten.
Die Verwendung von Makros in einer Source:- oder Patch:-Zeile ist eine Stilfrage. Manche schätzen die bessere Lesbarkeit einer Quellcodezeile ohne Makros. Andere bevorzugen die einfachere Aktualisierung auf neue Versionen durch die Verwendung von Makros. In jedem Fall sollten Sie in Ihrer Spec-Datei auf Konsistenz achten und die Gültigkeit der angegebenen URLs überprüfen. Das Werkzeug spectool (aus dem Paket rpmdevtools) kann Ihnen dabei helfen, festzustellen, ob eine URL Makros enthält.
Wenn Sie die tatsächliche Zeichenkette ermitteln müssen, wenn diese Makros enthält, können Sie rpm verwenden. Um beispielsweise den tatsächlichen Wert von „Source:“ zu ermitteln, können Sie Folgendes ausführen:
rpm -q --specfile foo.spec --qf "$(grep -i ^Source foo.spec)\n"
%autosetup
Alternativ zum üblichen %setup-Makro kann %autosetup verwendet werden. Zusätzlich zu den normalen %setup-Aufgaben wendet es automatisch alle in der Spec-Datei definierten Patch#-Elemente an. Es kann auch VCS-formatierte Patchdateien verarbeiten, dies erfordert jedoch zusätzliche BuildRequires und setzt voraus, dass alle Patchdateien in der Spec-Datei für diesen einen VCS-Typ formatiert sind. Aus diesem Grund wird nicht empfohlen, ein VCS mit %autosetup anzugeben. Weitere Informationen zur korrekten Verwendung von %autosetup finden Sie in der RPM-Dokumentation.
Verwendung von %{buildroot} und %{optflags} im Vergleich zu $RPM_BUILD_ROOT und $RPM_OPT_FLAGS
Es gibt zwei Möglichkeiten, das RPM-BuildRoot und die Optimierungsflags in einer Spec-Datei zu definieren:
Makro-Stil |
Variablenstil |
|
BuildRoot |
%{buildroot} |
$RPM_BUILD_ROOT |
Opt. Flags |
%{optflags} |
$RPM_OPT_FLAGS |
Es bringt wenig, einen Stil wegen deutlicher Vorteile zu bevorzugen, da beide in allen Fällen zu denselben Werten führen. Wählen Sie einen Stil und verwenden Sie ihn einheitlich für Ihre gesamte Verpackung.
Die Vermischung der beiden Stile ist zwar grundsätzlich zulässig, aber aus Sicht der Qualitätssicherung und Benutzerfreundlichkeit schlecht und sollte in Fedora-Paketen unterbleiben.
Warum das Makro %makeinstall nicht verwendet werden sollte
Das Fedora-RPM enthält ein %makeinstall-Makro, das jedoch NICHT verwendet werden darf, solange make install DESTDIR=%{buildroot} funktioniert. %makeinstall ist eine Notlösung, die zwar mit Makefiles funktioniert, die die Variable DESTDIR nicht verwenden, aber folgende potenzielle Probleme mit sich bringt:
-
%makeinstallsetzt während „make install“ eine Reihe von Make-Variablen außer Kraft und stellt den Pfad %{buildroot} voran, d.h. es führt make prefix="%{buildroot}%{_prefix}" libdir="%{buildroot}%{_libdir} …". aus. -
Es ist fehleranfällig und kann unerwartete Auswirkungen haben, wenn es mit nicht fehlerfreien Makefiles ausgeführt wird, z.B. kann der Buildroot-Pfad in installierten Dateien enthalten sein, in denen Variablen während der Installation ersetzt werden.
-
Beim Ausführen von „make install“ kann es zu unnötigen und fehlerhaften Rebuilds kommen, da die Make-Variablen andere Werte als im Abschnitt %build haben.
-
Wenn ein Paket libtool-Archive enthält, kann dies dazu führen, dass beschädigte *.la-Dateien installiert werden.
Stattdessen sollten Fedora-Pakete Folgendes verwenden: %make_install (Beachten Sie den Unterstrich!),make DESTDIR=%{buildroot} install oder make DESTDIR=$RPM_BUILD_ROOT install. Alle diese Befehle bewirken dasselbe.
Bauzeit-Makros für Source-RPMs
Alle Makros in Summary: und %description müssen expandierbar sein, während das SRPM gebaut wird. Da SRPMs ohne die BuildRequires des Pakets erstellt werden, kann die Abhängigkeit von Makros, die außerhalb der Spec-Datei definiert sind, leicht dazu führen, dass die nicht erweiterbaren Makros im erstellten SRPM erscheinen. Eine Möglichkeit zur Überprüfung besteht darin, ein minimales Chroot-Verzeichnis zu erstellen und das SRPM zu bauen:
mock --init mock --copyin [SRPM] / mock --shell bash rpm -ivh [SRPM] cd /builddir/build/SPECS rpmbuild -bs --nodeps [SRPM] rpm -qpiv /builddir/build/SRPMS/[SRPM]
Prüfen Sie die Ausgabe von rpm auf nicht expandierte Makros (%{foo}) oder fehlende Informationen (wenn %{?foo} zu einer leeren Zeichenkette expandiert wird). Noch einfacher ist es, Makros in Summary: und %description zu vermeiden, es sei denn, sie sind in der aktuellen Spec-Datei definiert.
Unsachgemäße Verwendung von %_sourcedir
Pakete, die als Source#-Dateien gekennzeichnete Dateien verwenden, müssen auf diese Dateien über ihren Makronamen Source# verweisen und dürfen nicht $RPM_SOURCE_DIR oder %{sourcedir} verwenden, um auf diese Dateien zu verweisen. Weitere Details finden Sie unter Packaging:RPM_Source_Dir.
Makros für Software Collections
Die Software Collections dienen dazu, Pakete von regulären Paketen zu trennen, ähnlich wie MingW-Pakete verwaltet werden.
Früher durften SCL-Makros in regulären Paketen enthalten sein, solange sie nicht verwendet wurden. Da wir nun SCLs erstellen, erzwingen wir eine strikte Trennung. Pakete MÜSSEN aktualisiert werden, um SCL-Makros auf Pakete zu beschränken, die ausdrücklich als Teil einer SCL genehmigt wurden.
Paketierung zusätzlicher RPM-Makros
Zusätzliche RPM-Makros müssen in %{_rpmmacrodir} gespeichert werden. Sie müssen nach dem Schema „macros.$PAKET“ benannt werden (z.B. macros.perl).
Normalerweise werden diese Dateien im Teilpaket -devel paketiert, da sie üblicherweise nur zum Erstellen anderer Pakete benötigt werden. In manchen Situationen ist dies jedoch nicht immer optimal, und Paketersteller werden angehalten, nach bestem Wissen und Gewissen das passende Paket für diese Dateien auszuwählen. RPM-Makrodateien dürfen nicht mit %config gekennzeichnet werden.
Skripte innerhalb von Spec-Dateien
Manchmal ist es notwendig, ein kurzes Skript (vielleicht einen Einzeiler) zu schreiben, das in den Abschnitten %prep, %build oder %install einer Spec-Datei ausgeführt wird, um Informationen über die Build-Umgebung zu erhalten. Um den Abhängigkeitsgraphen zu vereinfachen, sollten Spec-Dateien für diesen Zweck nur die folgenden Sprachen verwenden:
-
Python
-
Perl
-
In der Shell-Programmierung verwendete Standardprogramme, wie gawk oder sed
-
Lua (wie vom nativen Lua-Interpreter in RPM unterstützt)
Wenn Ihr Paket ohne eine bestimmte Skriptsprache (wie Ruby oder Tcl) nicht gebaut werden kann und daher bereits eine BuildRequires-Anweisung für diese Sprache enthält, kann diese auch aus der Spec-Datei aufgerufen werden.
Hinweis: Wenn Sie Perl oder Python in Ihrer Spec-Datei verwenden (und es sich nicht bereits um eine BuildRequires-Anweisung für das Paket handelt), müssen Sie explizit eine BuildRequires-Anweisung für Perl oder Python hinzufügen.
%global gegenüber %define bevorzugen
Verwenden Sie %global anstelle von %define, es sei denn, Sie benötigen wirklich nur lokal definierte Submakros innerhalb anderer Makrodefinitionen (ein sehr seltener Fall).
Begründung: Die beiden Makrodefinitionsanweisungen verhalten sich gleich, wenn sie sich auf der obersten Ebene der Verschachtelungsebene von rpm befinden.
Werden sie jedoch in verschachtelten Makroerweiterungen verwendet (wie in %{!?foo: ... }-Konstrukten), so gilt %define theoretisch nur bis zur schließenden Klammer (lokaler Gültigkeitsbereich), während %global-Definitionen globalen Gültigkeitsbereich haben.
Beachten Sie, dass sich %define und %global nicht nur im Gültigkeitsbereich unterscheiden: Der Textkörper eines mit %define definierten Makros wird erst bei Verwendung expandiert, der Textkörper von %global hingegen bereits bei der Definition. Mithilfe von %%-Maskierung lässt sich die verzögerte Expansion von %global erzwingen.
Umgang mit Locale-Dateien
Übersetzungsdateien werden möglicherweise von verschiedenen Programmen für unterschiedliche Frameworks verarbeitet. Stellen Sie sicher, dass Sie BuildRequires: für das richtige Paket hinzufügen, da Ihr Paket sonst möglicherweise keine Übersetzungsdateien im Buildroot generiert.
Falls das Paket gettext für Übersetzungen verwendet, fügen Sie Folgendes hinzu:
BuildRequires: gettext
Für Qt-basierte Pakete, die die Linguist-Toolchain verwenden, fügen Sie für die Lokalisierungs-Dienstprogramme das entsprechende qtX-linguist-Paket hinzu.
BuildRequires: qt6-linguist
Wenn Sie nur wenige Sprachdateien haben, die für ein einziges Paket nicht zu umfangreich wären,können Sie das Makro %find_lang verwenden (falls Sie Ihr Paket in separate Sprachpakete aufteilen müssen, lesen Sie bitte die Richtlinien für Sprachpakete). Dieses Makro findet alle zu Ihrem Paket gehörenden Sprachdateien (anhand des Namens) und speichert die Liste in einer Datei. Anschließend können Sie diese Datei verwenden, um alle Sprachdateien einzubinden. %find_lang sollte im Abschnitt %install Ihrer Spec-Datei ausgeführt werden, nachdem alle Dateien im Buildroot installiert wurden. Die korrekte Syntax für %find_lang lautet üblicherweise:
%find_lang %{name}
In manchen Fällen verwendet die Anwendung möglicherweise einen anderen Namen („name“) für ihre Sprachdateien.Sie müssen gegebenenfalls die Sprachdateien überprüfen und deren Namen ermitteln.Wenn sie beispielsweise meineanwendung.mo heißen, müssen Sie meineanwendung anstelle von %{name} an %find_lang übergeben. Nach der Ausführung von %find_lang wird eine Datei im aktiven Verzeichnis (standardmäßig im Verzeichnis der obersten Ebene des Quellverzeichnisses) erstellt. Der Name dieser Datei richtet sich nach der Option, die Sie dem Makro %find_lang übergeben haben. Üblicherweise lautet der Name %{name}.lang. Diese Datei sollten Sie anschließend in der Liste %files verwenden, um die von %find_lang erkannten Sprachdateien einzubinden. Dazu fügen Sie sie mit dem Parameter -f zu %files hinzu.
%files -f %{name}.lang
%{_bindir}/foobar
...
Beachten Sie, dass %find_lang zwar standardmäßig nach gettext-Sprachdateien sucht, aber auch Qt-Übersetzungen, lokalisierte Handbuchseiten und Hilfedateien verarbeiten kann.
Verwenden Sie Folgendes, um GNOME-Hilfedateien in /usr/share/gnome/help/ zu installieren:
%find_lang %{name} --with-gnome
Verwenden Sie Folgendes, um KDE-Hilfedateien in /usr/share/doc/HTML/ zu installieren:
%find_lang %{name} --with-kde
Verwenden Sie Folgendes, um binäre Qt-Übersetzungsdateien (.qm) zu verarbeiten:
%find_lang %{name} --with-qt
Verwenden Sie Folgendes, um übersetzte Handbuchseiten (Manpages) zu verarbeiten (dies schließt nicht die nicht übersetzten Handbuchseiten ein):
%find_lang %{name} --with-man
Rufen Sie /usr/lib/rpm/find-lang.sh im Terminal auf, um alle Optionen zu sehen.
Namen, die von %{name} abweichen (z.B. mehrere Manpages), müssenüber separate Aufrufe von %find_lang verarbeitet werden.
Hier ist ein Beispiel für die korrekte Verwendung von %find_lang in foo.spec mitder Anwendung „foo“, die mit gettext lokalisiert wurde, und Manpages namens „bar“ anstatt „foo“:
Name: foo
...
%prep
%setup -q
%build
%configure --with-cheese
make %{?_smp_mflags}
%install
make DESTDIR=%{buildroot} install
%find_lang %{name}
%find_lang bar --with-man
%files -f %{name}.lang -f bar.lang
%license LICENSE
%doc README
%{_bindir}/%{name}
%{_mandir}/man1/bar.1*
%changelog
* Fri Jan 13 2012 Karel Volny <kvolny@redhat.com> 0.1-2
- add man pages example
* Thu May 4 2006 Tom "spot" Callaway <tcallawa@redhat.com> 0.1-1
- sample spec that uses %%find_lang
Warum müssen wir %find_lang verwenden?
Die Verwendung von %find_lang trägt dazu bei, die Spec-Datei einfach zu halten und verschiedene andere Paketierungsfehler zu vermeiden.
-
Pakete, die
%{_datadir}/*verwenden, um alle Sprachdateien in einer Zeile abzurufen, erwerben dadurch auch die Besitzrechte an den Sprachverzeichnissen, was nicht zulässig ist. -
Die meisten Pakete, die Sprachdateien enthalten, haben sehr viele davon. Mit
%find_langist es in der Spec-Datei wesentlich einfacher, als wenn Sie Folgendes tun müssten:
%{_datadir}/locale/ar/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/be/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/cs/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/de/LC_MESSAGES/%{name}.mo
%{_datadir}/locale/es/LC_MESSAGES/%{name}.mo
...
-
Wenn in späteren Paketversionen neue Sprachdateien erscheinen, werden diese von
%find_langautomatisch beim Ausführen eingebunden, so dass Sie die Spec-Datei nicht unnötig oft aktualisieren müssen.
Beachten Sie, dass Sie %find_lang in Paketen mit lokalisierten Dateien verwenden MÜSSEN, es sei denn, die lokalisierten Dateien sind in Sprachpaketen aufgeteilt. In diesem Fall sollten Sie die Richtlinien für Sprachpakete befolgen.
Protokolldateien
Pakete, die Protokolldateien erzeugen, sollten diese in einem paketspezifischen (und dem Paket zugeordneten) Verzeichnis unter %{_localstatedir}/log speichern. Sofern die paketierte Software ihre Protokolle nicht selbst rotiert, muss sie außerdem eine Logrotate-Konfigurationsdatei zur Rotation ihrer Protokolldatei(en) mitliefern.
Konfigurationsdatei von logrotate
Die Logrotate-Konfigurationsdateien sollten so benannt werden, dass sie dem Namen des Daemons bzw. der Software entsprechen, die die Protokolle generiert. Dieser Name ist üblicherweise (aber nicht immer) identisch mit dem Paketnamen. Im Zweifelsfall verwenden Sie „%{name}.conf“. Diese Dateien müssen in %{_sysconfdir}/logrotate.d abgelegt werden und die Standarddateiberechtigungen (0644) und den Standardbesitz (root:root) verwenden.
Da es sich dabei um Konfigurationsdateien handelt, müssen sie in der %files-Liste als %config(noreplace) aufgeführt werden.
Beispiel einer minimalen Konfigurationsdatei für logrotate
/var/log/example/*log {
missingok # If the log file is missing, go on to the next one without issuing an error message
notifempty # Don't do any rotation if the logfile is empty
compress # Compress older files with gzip
delaycompress # Don't compress yesterdays files
}
Zeitstempel
Beim Hinzufügen von Befehlen zum Kopieren von Dateien in der Spec-Datei sollten Sie einen Befehl verwenden, der die Zeitstempel der Dateien beibehält, z.B. cp -p oder install -p.
Beim Herunterladen von Quellcode, Patches usw. empfiehlt sich die Verwendung eines Clients, der die Upstream-Zeitstempel beibehält. Beispiele hierfür sind wget -N oder curl -R. Um die Änderung für wget global zu aktivieren, fügen Sie Folgendes zu Ihrer ~/.wgetrc hinzu: timestamping = on. Für curl fügen Sie Folgendes zu Ihrer ~/.curlrc hinzu: -R.
Paralleles Make
Wo immer es möglich ist, sollte make wie folgt aufgerufen werden:
%make_build
Dies beschleunigt im Allgemeinen die Bauprozesse, insbesondere auf SMP-Maschinen.
Stellen Sie jedoch sicher, dass das Paket auf diese Weise fehlerfrei erstellt wird, da einige Make-Dateien die parallele Erstellung nicht unterstützen. Daher sollten Sie Folgendes in Betracht ziehen:
%_smp_mflags -j3
Fügen Sie dies zu Ihrer Datei ~/.rpmmacros hinzu – selbst auf UP-Maschinen – da dadurch die meisten dieser Fehler aufgedeckt werden.
Scriptlets
Pakete können Laufzeitcode enthalten, der während DNF-Transaktionen ausgeführt wird. Diese Codeabschnitte werden als Scriptlets bezeichnet und sind hier dokumentiert.
Bauskripte
Die Bauskripte der Pakete (%prep, %build, %install, %check und %clean) dürfen nur Dateien unter %{buildroot}, %{_builddir} und gültigen temporären Verzeichnissen wie /tmp, /var/tmp (oder $TMPDIR oder %{_tmppath}, wie vom rpmbuild-Prozess festgelegt) gemäß der folgenden Matrix ändern (erstellen, ändern, löschen):
/tmp, /var/tmp, $TMPDIR, %{_tmppath} |
%{_builddir} |
%{buildroot} |
|
%prep |
ja |
ja |
nein |
%build |
ja |
ja |
nein |
%install |
ja |
ja |
ja |
%check |
ja |
ja |
nein |
%clean |
ja |
ja |
ja |
Zur weiteren Klarstellung: Das sollte unabhängig von der Benutzerkennung des Paketerstellers gelten.
Pakete unter anderen Benutzerkonten erstellen
Beim Erstellen von Software, für die Sie kein vollständiges Sicherheitsaudit durchgeführt haben, schützen Sie sensible Daten wie Ihren privaten GPG-Schlüssel in einem separaten Benutzerkonto.
Dasselbe gilt für Reviewer/Tester. Erstellen Sie Pakete Source-RPMs in einem separaten Konto neu, das keinen Zugriff auf sensible Daten hat.
Verschiebbare Pakete
Von der Verwendung der RPM-Funktion zum Generieren verschiebbarer Pakete wird dringend abgeraten. Sie ist schwierig korrekt zu implementieren, weder über den Installer noch über yum nutzbar und in der Regel nicht erforderlich, wenn andere Paketierungsrichtlinien befolgt werden. Sollten Sie jedoch ausnahmsweise einen triftigen Grund haben, ein Paket verschiebbar zu gestalten, MÜSSEN Sie diese Absicht und Begründung in Ihrem Antrag auf Paketprüfung angeben.
Eigentümerschaft von Dateien und Verzeichnissen
Ihr Paket sollte alle Dateien enthalten, die im Rahmen des Installationsprozesses installiert werden.
In den meisten Fällen ist es nicht erforderlich, dass mehrere Pakete identische Kopien derselben Datei enthalten. Sollte dies jedoch notwendig sein, können mehrere Pakete durchaus identische Kopien derselben Datei enthalten, sofern die folgenden Anforderungen erfüllt sind:
-
Die Pakete, die die identischen Dateien gemeinsam besitzen, werden aus einem einzigen SRPM erstellt.
ODER
-
Die Pakete, die die gleichen Dateien gemeinsam besitzen, bilden keine Abhängigkeitskette (z.B. wenn Paket A Paket B benötigt, sollten sie nicht beide die gleichen Dateien enthalten; entweder A oder B muss die gemeinsamen Dateien besitzen, aber nicht beide).
Darüber hinaus werden identische Dateien als Dateien definiert, die in jedem Paket hinsichtlich Inhalt, Prüfsumme, Zugriffsrechten und Speicherort im Dateisystem immer identisch sind.
Ein wichtiger Dateityp, der häufig in allen Teilpaketen identisch verwendet wird, ist der Lizenztext. In bestimmten Fällen ist es erforderlich, den Lizenztext in mehreren %files-Abschnitten innerhalb eines Pakets zu duplizieren. Weitere Informationen finden Sie unter Subpackage Licensing.
Die Verzeichniseigentümerschaften sind etwas komplexer als die von Dateien. Pakete müssen alle Verzeichnisse besitzen, in denen sie Dateien ablegen, mit folgenden Ausnahmen:
-
alle Verzeichnisse, die dem
filesystem, demmanoder anderen explizit erstellten-filesystem-Paketen gehören. -
alle Verzeichnisse, die anderen Paketen in der nativen Abhängigkeitskette Ihres Pakets gehören
In diesem Kontext wird die „native Abhängigkeitskette“ eines Pakets als die Menge der Pakete definiert, die für die normale Funktion dieses Pakets notwendig sind. Genauer gesagt: Sie müssen ein Paket nicht allein deshalb in die Abhängigkeiten einbeziehen, weil es zufällig ein Verzeichnis besitzt, in dem Ihr Paket Dateien ablegt. Wenn Ihr Paket dieses Paket bereits aus anderen Gründen benötigt, sollte es dieses Verzeichnis nicht auch besitzen.
Wir wollen in jedem Fall verhindern, dass nicht zugeordnete Verzeichnisse auf einem System vorhanden sind. Weitere Informationen finden Sie unter Packaging:Nicht zugeordnete Verzeichnisse.
| Bei gemeinsamem Besitz von Verzeichnissen müssen Sie sicherstellen, dass die Besitzverhältnisse und Berechtigungen des Verzeichnisses in allen Paketen, denen es gehört, übereinstimmen. |
Hier sind Beispiele, die beschreiben, wie die meisten Fälle von Verzeichnisbesitz gehandhabt werden.
Das Verzeichnis ist vollständig in Ihrem Paket enthalten oder ist für Kernfunktionen Ihres Pakets relevant.
Ein Beispiel:
gnucash platziert viele Dateien im Verzeichnis /usr/share/gnucash
Lösung: Das Paket gnucash sollte Eigentümer des Verzeichnisses /usr/share/gnucash sein.
Das Verzeichnis gehört auch einem Paket, das die erforderliche Funktionalität Ihres Pakets implementiert.
Ein Beispiel:
pam besitzt das Verzeichnis /etc/pam.d. gdm speichert Dateien in /etc/pam.d. gdm benötigt pam für die normale Funktion und benötigt daher „Require: pam“ zusätzlich zum Verzeichnisbesitz (entweder implizit oder explizit).
Lösung: Das Paket pam sollte das Verzeichnis /etc/pam.d besitzen, und`gdm` sollte das Paket pam mit Require: als Abhängigkeit anfordern.
Das Verzeichnis gehört einem Paket, das für die Funktion Ihres Pakets nicht erforderlich ist.
Manche Pakete erstellen und besitzen Verzeichnisse, um anderen Paketen das Speichern geeigneter Dateien zu ermöglichen, aber diese anderen Pakete benötigen das ursprüngliche Paket nicht, um ordnungsgemäß zu funktionieren.
Ein Beispiel:
gtk-doc besitzt das Verzeichnis /usr/share/gtk-doc/ evolution legt Dateien in /usr/share/gtk-doc/ ab evolution benötigt gtk-doc nicht, um ordnungsgemäß zu funktionieren. Nichts in der Abhängigkeitskette von evolution besitzt das Verzeichnis /usr/share/gtk-doc/.
Lösung: Das Paket evolution sollte Eigentümer des Verzeichnisses /usr/share/gtk-doc sein. Es ist nicht nötig, ein explizites „Requires“ für gtk-doc allein wegen der Verzeichnisberechtigung hinzuzufügen.
Manchmal ist es vorteilhaft, wenn solche Verzeichnisse einem „künstlichen Dateisystem“-Paket wie mozilla-filesystem gehören. Diese Pakete sind so konzipiert, dass sie explizit eingebunden werden müssen, wenn andere Pakete Dateien in ihren Verzeichnissen speichern. Daher sollten diese Pakete in solchen Fällen das „künstliche Dateisystem“-Paket explizit einbinden und nicht mehrere eigene Verzeichnisse erstellen. Paketierer sollten die Anzahl der betroffenen Verzeichnisse und Pakete berücksichtigen, wenn sie entscheiden, ob sie „künstliche Dateisystem“-Pakete erstellen, und nach bestem Wissen und Gewissen entscheiden, ob dies notwendig ist oder nicht.
| Faustregel: Bei der Beurteilung, ob diese Ausnahme zutrifft, sollten Paketierer und Reviewer sich folgende Frage stellen: Erweitern oder ergänzen die Dateien in diesem gemeinsamen Verzeichnis die Funktionalität eines anderen Pakets, wobei dieses andere Paket für die primäre Funktionalität dieses Pakets nicht erforderlich ist? |
Das Paket, von dem Ihr Paket abhängig ist, um ein Verzeichnis bereitzustellen, kann in einer späteren Version ein anderes Verzeichnis verwenden. Ihr Paket wird mit dieser späteren Version unverändert funktionieren.
Ein Beispiel mit Perl-Modulen:
Angenommen, perl-A-B hängt von perl-A ab und installiert Dateien in /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A/B. Das Perl-Basispaket garantiert, dass es /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi so lange besitzt, wie es zur Version 5.8.8 kompatibel ist. Eine zukünftige Aktualisierung des Pakets perl-A könnte jedoch in /usr/lib/perl5/vendor_perl/5.9.0/i386-linux-thread-multi/A installieren (und somit dieses Verzeichnis besitzen). Das Paket perl-A-B muss also sowohl /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A als auch /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A/B besitzen, um die korrekten Besitzverhältnisse zu gewährleisten.
Dateizugriffsrechte
Die Dateizugriffsrechte MÜSSEN korrekt gesetzt sein. Dateien im Verzeichnis /usr sollten dem Benutzer root:root gehören, es sei denn, aus Sicherheitsgründen ist ein spezifischerer Benutzer oder eine Gruppe erforderlich. Sie MÜSSEN für alle Benutzer lesbar (und gegebenenfalls ausführbar) sein. Dateien außerhalb von /usr SOLLTEN dem Benutzer root:root gehören und für alle Benutzer lesbar (und gegebenenfalls ausführbar) sein, es sei denn, die Umstände erfordern etwas anderes.
Der Standarddateimodus ist 0644 oder 0755. Verzeichnisse sollten den Modus 0755 haben. Die meisten Bauskripte und RPM-Pakete verwenden diese Standardeinstellungen. Wenn das Verzeichnis für eine Gruppe beschreibbar sein soll, muss auch das Setgid-Bit gesetzt sein, damit die darin geschriebenen Dateien der entsprechenden Gruppe gehören. Diese Verzeichnisse sollten den Modus 2775 haben.
Die %defattr-Anweisung in der %files-Liste SOLLTE NUR verwendet werden, wenn ein Wert festgelegt wird, der nicht dem Standardwert entspricht, oder um nach dem Festlegen eines solchen Werts auf den Standardwert zurückzukehren.
Explizite Listen
Paketierer SOLLTEN NICHT einfach alles in ein gemeinsames Verzeichnis kopieren.
Speziell Folgendes SOLLTE NICHT in %files verwendet werden:
-
%{_bindir}/* -
%{_datadir}/* -
%{_includedir}/* -
%{_mandir}/* -
%{_docdir}/*
Diese Regel dient als Kontrollmechanismus gegen häufige Fehler, die sonst schwer zu erkennen wären. Sie schränkt jedoch einige Automatisierungsmöglichkeiten ein.
Der häufigste Fehler, den diese Regel verhindert, ist das Hinzufügen neuer Befehle in`%{_bindir}/*`. Sie sollten solche Änderungen immer unter Konflikte überprüfen und die Listesolcher Dateien explizit und nachvollziehbar führen.
Benutzer und Gruppen
Manche Pakete benötigen oder nutzen dedizierte Laufzeitbenutzer- und/oder Gruppenkonten. Richtlinien für den Umgang mit diesen Fällen finden Sie in einem separaten Dokument.
Beachten Sie: Für Fedora bereitgestellte Systemdienste DÜRFEN NICHT als Benutzer nobody ausgeführt werden, sondern müssen stattdessen einem eigenen Systembenutzer zugewiesen werden.
Web-Anwendungen
Web-Anwendungen, die in Fedora paketiert sind, sollten ihren Inhalt in /usr/share/%{name} und NICHT in /var/www/ ablegen. Dies geschieht aus folgendem Grund:
-
Das Verzeichnis /var ist für variable Datendateien und Protokolle vorgesehen. /usr/share ist dafür wesentlich besser geeignet.
-
Viele Benutzer haben bereits Inhalte in /var/www, und wir möchten nicht, dass irgendein Fedora-Paket diese überschreibt.
-
/var/www wird vom Dateisystemhierarchie-Standard nicht mehr spezifiziert
Konflikte
Fedora-Pakete sollten nach Möglichkeit Konflikte vermeiden. Leider ist dies nicht immer möglich. Ausführliche Informationen zur Konfliktrichtlinie von Fedora finden Sie unter: Konflikte.
Werkzeuge wie „Alternativen“ und „Umgebungsmodule“ können auch dabei helfen, Paketkonflikte zu vermeiden.
Alternativen
Das Werkzeug „Alternatives“ ermöglicht die parallele Installation von Paketen, die dieselbe Funktionalität durch die Verwaltung von symbolischen Links bereitstellen. Ausführliche Informationen zur korrekten Verwendung von Alternatives finden Sie hier.
Umgebungsmodule
Wenn mehrere Varianten existieren, die jeweils die Bedürfnisse eines Benutzers erfüllen und daher gleichzeitig für alle Benutzer verfügbar sein müssen, reicht das „Alternativen“-System allein nicht aus, da es systemweit gilt. In solchen Situationen können „Umgebungsmodule“ Konflikte vermeiden. Ausführliche Informationen zur deren korrekter Verwendung finden Sie hier.
Patch-Richtlinien
Alle Patches sollten einen Link zu einem Bugreport im Upstream-Projekt oder einen Kommentar enthalten
Alle Patches in Fedora-Spec-Dateien SOLLTEN einen Kommentar zu ihrem Upstream-Status enthalten. Jedes Mal, wenn Sie einen Patch erstellen, ist es ratsam, ihn in einem Upstream-Bugtracker einzureichen und einen Link dazu im Kommentar über dem Patch anzugeben. Zum Beispiel:
# https://bugzilla.gnome.org/show_bug.cgi?id=12345
Patch: gnome-panel-fix-frobnicator.patch
Das ist völlig in Ordnung; falls Sie es jedoch mögen, kann ein kurzer Kommentar dazu, was der obige Patch bewirkt, hilfreich sein:
# Don't crash with frobnicator applet
# https://bugzilla.gnome.org/show_bug.cgi?id=12345
Patch: gnome-panel-fix-frobnicator.patch
Das Senden von Patches an die Upstream-Entwickler und das Hinzufügen dieses Kommentars trägt dazu bei, dass Fedora sich als verantwortungsbewusstes Mitglied der FLOSS-Community verhält (Staying Close to Upstream Projects). Es hilft anderen (und auch Ihnen) bei der zukünftigen Paketpflege, da so bekannt ist, welche Patches voraussichtlich in einer neuen Upstream-Version enthalten sein werden.
Falls das Upstream-Projekt keine Bugtracker hat
Sie können angeben, dass Sie den Patch an die Upstream-Entwickler gesendet haben und welcher Status Ihnen bekannt ist:
# Sent upstream via email 20080407
Patch: foobar-fix-the-bar.patch
# Upstream has applied this in SVN trunk
Patch: foobar-fix-the-baz.patch
Fedora-spezifische (oder von Upstream-Entwicklern abgelehnte) Patches
Es kann sein, dass einige Patches tatsächlich Fedora-spezifisch sind; in diesem Fall sollte dies wie folgt angegeben werden:
# This patch is temporary until we land the long term System.loadLibrary fix in OpenJDK
Patch: jna-jni-path.patch
Anwenden von Patches
Normalerweise sollten Patches für ein Paket in PatchN:-Tags in der RPM-Spec-Datei aufgeführt und mithilfe der Makros %patch oder %autosetup angewendet werden. Die Dateien müssen anschließend in das Fedora-Paketversionskontrollsystem eingecheckt werden (derzeit die Git-Repositories auf pkgs.fedoraproject.org, üblicherweise aufgerufen über fedpkg). Durch diese Speicherung können Standardwerkzeuge verwendet werden, um die Änderungen zwischen den Dateiversionen zu visualisieren und Hinzufügungen und Entfernungen ohne zusätzliche Umwege (wie sie bei der Verwendung von Lookaside-Dateien auftreten würden) nachzuverfolgen.
Das direkte Anwenden von Patches aus dem RPM_SOURCE_DIR ist NICHT ZULÄSSIG. Die vollständige Begründung finden Sie unter $RPM_SOURCE_DIR oder %{_sourcedir}.
Der Paketbetreuer KANN von dieser Regel abweichen, wenn die Upstream-Version des Pakets einen extrem großen Patch oder ein Patch-Archiv für eine Basisversion bereitstellt. In diesem Fall KANN das Patch-Archiv als SourceN:-Zeile aufgeführt werden, und die Patches werden durch Entpacken des Archivs und anschließendes Anwenden der verteilten Patches mit dem regulären Befehl /usr/bin/patch angewendet. Zusätzliche Patches für das Paket (z.B. vom Fedora-Paketbetreuer zur Fehlerbehebung) MÜSSEN weiterhin in PatchN:-Zeilen aufgeführt und mit %patch-Makros angewendet werden, nachdem die Patches aus dem Patch-Archiv angewendet wurden. Paketbetreuer und Reviewer sollten bei der Anwendung dieser Ausnahme vorsichtig sein, da die Veröffentlichung einer Aktualisierung als Patchset ein Hinweis darauf sein kann, dass das Patchset nicht von der tatsächlichen Upstream-Version stammt oder dass die Patches auf Korrektheit überprüft werden sollten, anstatt sie einfach als Upstream-Codebasis zu akzeptieren.
Epochen verwenden
RPM unterstützt ein Feld namens „Epoch:“, ein numerisches Feld, das, falls gesetzt, einen weiteren Qualifikator für RPM-Paketvergleiche hinzufügt. Genauer gesagt: Ist die Epoche eines Pakets gesetzt, hat sie Vorrang vor allen anderen Vergleichen (außer bei einem größeren „Epoch:“-Wert). Ist die Epoche eines Pakets nicht gesetzt, behandelt RPM sie so, als wäre sie auf 0 gesetzt.
Beispiel:
Version: 1.2
Release: 3%{?dist}
Epoch: 1
Ein Paket mit diesen Definitionen wäre höherwertig als ein Paket mit einer höheren Versionsnummer oder einem höheren Release. Da „Epoch“ für Menschen verwirrend ist (und nach der Verwendung nicht mehr aus einem Paket entfernt werden kann), sollte es in Fedora nur als letztes Mittel zur Klärung der Aktualisierungsreihenfolge eines Pakets verwendet und nach Möglichkeit vermieden werden.
Außerdem verkompliziert die Verwendung von Epoch-Werten die üblichen Richtlinien für die Paketieruung. Wenn ein Paket eine Epoche verwendet, muss diese überall dort angegeben werden, wo %{version}-%{release} verwendet wird. Wenn beispielsweise ein abhängiges Paket eine Epoche hat, muss diese beim Hinzufügen einer versionierten Abhängigkeit aufgeführt werden:
Requires: foo = %{epoch}:%{version}-%{release}
Symlinks
Es gibt zwei Möglichkeiten, einen Symlink zu erstellen: einen relativen oder einen absoluten Link. In Fedora wird keine der beiden Methoden bevorzugt. Paketierer sollten nach bestem Wissen und Gewissen entscheiden, welche Methode zur Erstellung symbolischer Links am besten geeignet ist.
Relative Symlinks
Ein relativer Symlink verweist auf eine Datei oder ein Verzeichnis relativ zur Position des Links. Beispielsweise würde dieser Befehl einen relativen Symlink erstellen:
ln -s ../..%{_bindir}/foo %{buildroot}%{_bindir}/bar
Vorteile:
-
Relative symbolische Links verweisen innerhalb oder außerhalb eines Chroot-Verzeichnisses auf dieselbe Datei.
Nachteile:
-
Viel komplizierter zu erzeugen als absolute Symlinks
-
Relative Symlinks können fehlerhaft sein oder sich unerwartet verhalten, wenn ein Teil eines Dateisystems an einem benutzerdefinierten Speicherort eingebunden wird.
-
Relative symbolische Links können beim Bind-Einhängen oder beim Erstellen von Symlinks auf Verzeichnisse beschädigt werden.
-
Relative Symlinks können die Verwendung von RPM-Systemmakros erschweren.
Absolute Symlinks
Ein absoluter Symlink verweist auf einen absoluten Datei- oder Verzeichnispfad. Beispielsweise würde dieser Befehl einen absoluten Symlink erstellen:
ln -s %{_bindir}/foo %{buildroot}%{_bindir}/bar
Vorteile:
-
Viel einfacher zu erstellen als relative Symlinks.
-
Absolute Symlinks arbeiten beim Bind-Einhängen oder beim Erstellen von Symlinks auf Verzeichnisse zuverlässig.
-
Absolute symlinks funktionieren gut mit RPM-Systemmakros.
Nachteile:
-
Absolute Symlinks können bei Verwendung mit Chroots zu Fehlern führen.
Ersetzen eines Symlinks zu einem Verzeichnis oder eines Verzeichnisses zu einer Datei beliebigen Typs
In manchen Fällen erfordert das Ersetzen eines Symlinks zu einem Verzeichnis eine besondere Vorgehensweise. Beim Ersetzen eines Verzeichnisses durch eine beliebige Datei ist dies immer erforderlich.
In Ersetzen eines Symlinks durch ein Verzeichnis oder ein Verzeichnis durch eine Datei beliebigen Typs finden Sie Informationen dazu.
Test-Suiten
Wenn der Quellcode des Pakets eine Testsuite bereitstellt, sollte diese im Abschnitt %check ausgeführt werden, sofern dies praktikabel ist.
tmpfiles.d
Es gibt spezifische Richtlinien für den Umgang mit tmpfiles.d-Konfigurationen und -Verzeichnissen (in /run und /run/lock): Tmpfiles.d.
Umbenennen/Ersetzen oder Entfernen vorhandener Pakete
| Dem Prozess zur Umbenennung von Paketen sollte befolgt werden, wenn ein bestehendes Paket umbenannt wird. |
Sollte es notwendig werden, ein bestehendes Paket umzubenennen oder zu ersetzen, sollte die Änderung für Endbenutzer im neuen Paket – soweit anwendbar – transparent gestaltet werden.
Wird ein Paket umbenannt, ohne dass sich die Funktionalität ändert, oder ist es ein ausreichend kompatibler Ersatz für ein bestehendes Paket (wobei „ausreichend“ bedeutet, dass es nur Änderungen von der Größenordnung enthält, die üblicherweise bei Versionsaktualisierungen vorkommen), so stellen Sie saubere Aktualisierungspfade und Kompatibilität auf folgende Weise sicher:
Provides: alterpaketname = $provEVR
Obsoletes: alterpaketname < $obsEVR
$provEVR bezieht sich auf ein (Epochen-)Versions-Release-Tupel, das das ursprüngliche, unveränderte Paket gehabt hätte, wenn seine Version oder sein Release erhöht worden wäre. Normalerweise verwendet man hier Makros, da der Wert von provesEVR mit dem Versions- und Release-Fortschritt des umbenannten Pakets weiter steigen sollte. $obsEVR ist ein (Epochen-)Versions-Release-Tupel, das so angeordnet ist, dass ein sauberer Aktualisierungspfad vorhanden ist, ohne den Versionsbereich unnötig nach oben zu erweitern. Normalerweise verwendet man hierfür keine Makros, da man lediglich versucht, über die letzte bekannte Version unter dem alten Namen hinauszugehen.
Wenn ein Paket ein bestehendes Paket ersetzt, ohne ein ausreichend kompatibler Ersatz im oben definierten Sinne zu sein, verwenden Sie nur die Zeile Obsoletes: aus dem obigen Beispiel.
Berücksichtigen Sie %{?dist}:
Denken Sie bei der Festlegung des Wertes von $obsEVR
daran, dass dieser höher als der vorherige Wert von Release:
sein muss, einschließlich des Suffixes %{?dist}.
Beispiel: Wenn das Paket zuvor den Release-Tag -4.fcNN hatte,
sollte das in $obsEVR angegebene Release mindestens 5 sein.
|
Wenn das ersetzte Paket rpmautospec verwendet, kann man entweder im erstellten Paket nachsehen (z.B. in Koji), um den tatsächlichen Release-Tag des letzten Bauvorgangs zu finden, oder rpmautospec calculate-release verwenden, um die Release-Nummer zu berechnen.
|
Wenn stillgelegte Pakete von Endbenutzerrechnern entfernt werden müssen, weil sie Abhängigkeitsprobleme verursachen, die Aktualisierungen behindern oder anderweitig schädlich sind, sollte ein Paketierer beantragen, dass Obsoletes: zu fedora-obsolete-packages hinzugefügt wird. Erstellen Sie dazu hier einfach ein Bugzilla-Ticket. Bitte geben Sie an, welche Pakete als veraltet markiert werden müssen, welche genauen Versionen betroffen sind und warum sie nicht installiert bleiben dürfen.
Wenn das veraltete Paket eine Epoche hatte, muss diese sowohl in Provides: als auch in Obsoletes: beibehalten werden. Angenommen, foo wird in bar umbenannt, bar ist zu foo kompatibel und die letzte Version des foo-Pakets ist foo-1.0-3.fcNN mit Epoch: 2. Folgendes sollte dann zu bar hinzugefügt werden (und analog für alle Teilpakete, sofern zutreffend):
Provides: foo = 2:%{version}-%{release}
# Important: We set the Obsoletes release to 4 to be higher than the last build of foo
Obsoletes: foo < 2:1.0-4
Explizite Provides:-Anweisungen müssen berücksichtigen, ob das Paket Elemente bereitstellt, die architekturunabhängig oder architekturspezifisch verwendet werden können. Für Pakete, die nicht architekturunabhängig sind, sollte Provides: architekturspezifisch gemacht werden, indem das Makro %{?_isa} am Ende der Zeichenkette in „Provides:“ angehängt wird (z.B. Provides: foo%{?_isa} = 2:%{version}-%{release}). Pakete, die explizit architekturunabhängige Elemente bereitstellen (z.B. solche, deren Abhängigkeiten nicht dieselbe Architektur haben müssen), benötigen dieses Makro nicht. In manchen Fällen stellt ein Paket mehrere Elemente bereit, von denen einige nur von Abhängigkeiten derselben Architektur und andere von Abhängigkeiten beliebiger Architektur verwendet werden können. In solchen Fällen sind sowohl architekturspezifische als auch architekturunabhängige „Provides:“ gerechtfertigt.
Beispiele für Pakete, die explizit nur architekturspezifische Provides:-Informationen bereitstellen sollten, sind native Codebibliotheken oder Plug-ins und ihre zugehörigen -devel-Pakete. Pakete, die explizit nur architekturunabhängige Provides:-Informationen bereitstellen sollten, umfassen die meisten eigenständigen Programme (zusätzlich zu allen noarch-Paketen). Auch wenn diese Programme selbst architekturspezifisch sein können, sollte die Architektur für die Clients, die sie ausführen, in den meisten Fällen irrelevant sein. Ein Paket, das beispielsweise sowohl eine native Codebibliothek als auch eine Interpretersprachenschnittstelle zu dieser Bibliothek explizit bereitstellt, sollte sowohl architekturspezifische (für Clients der nativen Codebibliothek) als auch architekturunabhängige (für Clients der Interpretersprachenschnittstelle) Provides:-Informationen enthalten.
Wenn es keine Standardbenennung für ein Paket oder andere langfristige Namenskompatibilitätsanforderungen im Zusammenhang mit der Umbenennung gibt, sollte davon ausgegangen werden, dass die „Provides“ veraltet und nur von kurzer Dauer sind und in der Distributionsversion nach der nächsten entfernt werden (das heißt, wenn sie in FC-X eingeführt wurden, sollten sie in allen nachfolgenden Paketrevisionen für Distributionen FC-X und FC-(X+1) beibehalten und in FC-(X+2) entfernt werden). Die Distributionsversion, in der die Entfernung geplant ist, sollte in einem Kommentar in der Spec-Datei dokumentiert werden. Die Betreuer betroffener Pakete sollten benachrichtigt und dazu angehalten werden, auf den neuen Namen umzusteigen. Aufwärtskompatibilitäts-Provides in älteren Distributionszweigen können berücksichtigt werden, um es den Paketbetreuern zu ermöglichen, dieselben einfachen Spec-Dateien zwischen den Zweigen beizubehalten und dennoch auf den neueren Namen umzusteigen.
Für Pakete, die üblicherweise nicht über den Paketnamen als Abhängigkeit eingebunden werden, wie z.B. reine Bibliothekspakete (die über Bibliotheks-Soname-Abhängigkeiten eingebunden werden), ist das Hinzufügen von Provides normalerweise nicht erforderlich. Beachten Sie jedoch, dass die -devel-Teilpakete von Bibliothekspaketen als Bauabhängigkeiten über den Paketnamen eingebunden werden, so dass das Hinzufügen von Provides dort oft angebracht ist.
Ersetzung durch mehrere Pakete
Manchmal wird ein Paket in zwei oder mehr Pakete (entweder Teilpakete oder separate Quellpakete) aufgeteilt, um einige Komponenten optional zu gestalten. Benutzer der optionalen Teile sollen jedoch eine Aktualisierung durchführen können, ohne die Funktionalität zu verlieren. Daher müssen die neuen Pakete bei einer Aktualisierung von einer Version vor der Aufteilung mitinstalliert werden. Werden einige später entfernt, dürfen sie bei weiteren Aktualisierungen nicht erneut installiert werden.
Dies wird erreicht, indem in jedes der Pakete, die zusammen das ursprüngliche Paket ersetzen, ein Obsoletes:-Tag wie oben eingefügt wird. Existiert der Name des ursprünglichen Pakets nach der Aufteilung noch, muss sich dieses selbst als veraltet kennzeichnen. Selbst wenn ein optionales, ausgegliedertes Paket das ursprüngliche Paket benötigt, muss sich das ursprüngliche Paket dennoch selbst als veraltet kennzeichnen. Andernfalls wird das ausgegliederte Paket nicht eingebunden.
Beispiel: Die Version 3 von „Foo“ enthält „Bar“ als nicht essenzielle Komponente. In Version 4 wird „Bar“ in ein Teilpaket verschoben. „Bar“ darf bei der Aktualisierung nicht verloren gehen.
Name: foo
Version: 4
Release: 1%{?dist}
Obsoletes: foo < 4
%package bar
Requires: foo%{?_isa} = %{version}-%{release}
Obsoletes: foo < 4
Auf diese Weise hereingezogene Pakete werden von DNF 4 nicht als durch Benutzer installiert markiert, daher werden sie durch dnf autoremove entfernt. Dieses Problem scheint in DNF 5 behoben zu sein.
|
Pakete als veraltet markieren
Es gibt ein Verfahren, um anzuzeigen, dass ein Paket veraltet ist und möglicherweise in Zukunft aus der Distribution entfernt wird. Siehe Pakete als veraltet markieren.
Netzwerkunterstützung
Wenn eine Anwendung native und stabile Unterstützung für IPv4 und IPv6 bietet und IPv4 durch die Unterstützung für IPv6 nicht beeinträchtigt wird, dann MÜSSEN beide im Fedora-Paket aktiviert sein.
Cron-Dateien
Details zum Paketieren von Cron-Dateien finden Sie hier.
Sicherheitsaktualisierungen zum Beheben bekannter CVE-Probleme
Wenn eine Aktualisierung Ihres Pakets ein bekanntes Sicherheitsproblem (zum Zeitpunkt der Aktualisierung) mit einer zugehörigen CVE-Nummer (Common Vulnerabilities and Exposures) behebt, sollten Sie die CVE-Nummer im RPM-Änderungsprotokolleintrag angeben.
Netzwerkzugriff zur Bauzeit
Pakete im Fedora-Buildsystem werden in einem simulierten Chroot ohne Internetzugang erstellt. Pakete dürfen keine Netzwerkressourcen verwenden, die sie nicht selbst erzeugen (z.B. für Tests). Der Quellcode darf in keinem Fall von externen Quellen heruntergeladen werden, sondern ausschließlich aus dem Lookaside-Cache und/oder dem Fedora-Git-Repository.
Bootstrapping
Falls Ihr Paket zirkuläre Abhängigkeiten zur Bauzeit erzeugt, sollten Sie dieses Makro verwenden, um Ihr Paket zu initialisieren („Bootstrapping“):
# When we are bootstrapping, we drop some dependencies, and/or build time tests.
%bcond_with bootstrap
[...]
%if %{without bootstrap}
# dependencies for %%check
BuildRequires: foo
%endif
[...]
%if %{without bootstrap}
%check
make check
%endif
Seit Fedora 30
wird als angenehmer Nebeneffekt beim Aktivieren
des Bootstrapping-Modus das Suffix ~bootstrap an das
Dist-Tag angehängt. Dadurch entfällt die Notwendigkeit,
die Release-Version zwischen Bootstrapping und finalem Build zu erhöhen.
Sie können Bootstrapping temporär per Commit aktivieren,
wodurch %bcond_with bootstrap in %bcond_without bootstrap geändert
wird und den Commit später wieder rückgängig machen, um den
finalen Build durchzuführen.
|
Seit Fedora 31
kann die automatische Suffixergänzung deaktiviert
werden, indem Sie %global __bootstrap %{nil}
in Ihrer Spec-Datei angeben.
|
Wenn Ihr Paket explizit über Provides: eine Funktionalität bereitstellt, die beim Start fehlt, dann sollte diese Bereitstellung wie folgt aussehen:
%if %{without bootstrap}
Provides: bar(eine_funktionalität)
%endif
Bitte beachten Sie, dass die Verwendung vorkompilierter Binärdateien im Bootstrap-Prozess weiterhin eine Ausnahmegenehmigung des Packaging Committee erfordert, wie in der [General Exception Policy] beschrieben.
Kryptografische Systemregeln
Anwendungen, die die kryptografischen Protokolle SSL oder TLS verwenden, MÜSSEN den Kryptografie-Richtlinien folgen.
Shebang-Zeilen
Beim Paketieren von Skriptdateien, bei denen der zu verwendende Interpreter in der ersten Zeile des Skripts (der Shebang-Zeile) nach #! angegeben wird, gelten die folgenden Regeln:
-
Die Pfade
env,/bin/envund/usr/bin/envDÜRFEN NICHT verwendet werden. Der Interpreter, der zum Ausführen von paketierten Anwendungen verwendet wird, darf nicht von den Pfaden im persönlichen$PATHdes Benutzers abhängen. -
Dateien, die nicht als ausführbare Dateien installiert werden, SOLLTEN KEINE Shebang-Zeilen enthalten.
-
Für sprachspezifische Richtlinien können zusätzliche Einschränkungen gelten.
Shebang-Zeilen für ausführbare Skripte werden automatisch angepasst, um Aufrufe von env in die direkte Verwendung der entsprechenden ausführbaren Datei in /usr/bin umzuwandeln. Verschiedene Prüfungen stellen sicher, dass die Shebang-Zeilen gültig sind, und der Bauprozess kann dadurch fehlschlagen. Schließlich können auch weitere sprachspezifische Anpassungen vorgenommen werden. Daher ist es im Allgemeinen unnötig, ausführbare Skripte manuell zu ändern, um die Verwendung von env zu korrigieren, solange diese Funktionalität aktiviert ist.
Falls die automatischen Prüfungen und Änderungen ein Paket beschädigen, gibt es zwei primäre Optionen:
-
Der Paketersteller kann die Shebang-Zeilen manuell korrigieren (durch Patches, Skripten mittels sed oder ähnlichen Methoden).
-
Der Paketersteller kann die Ausführungsberechtigung für das Skript entfernen, so dass die Prüfungen und Änderungen nicht durchgeführt werden.
Wenn das Skript ausführbar bleiben muss (und nur dann!) und nicht so verändert werden kann, dass es die Prüfungen besteht, kann der Betreuer die Prüfungen und Änderungen deaktivieren. Es ist auch möglich, die Funktionalität für bestimmte Pfade oder Shebang-Zeilen zu deaktivieren, indem __brp_mangle_shebangs_exclude_from bzw. %__brp_mangle_shebangs_exclude gesetzt werden. Die Syntax entspricht den Einstellungen in Packaging:AutoProvidesAndRequiresFiltering. Alternativ kann die Funktionalität vollständig deaktiviert werden, indem %undefine __brp_mangle_shebangs am Anfang der Spec-Datei hinzugefügt wird.
BRP-Skripte (BuildRoot Policy)
BRP-Skripte werden am Ende von %install (über das Makro %__os_install_post) eingefügt und führen automatische Plausibilitätsprüfungen bzw. Anpassungen an den im Build-Root installierten Dateien durch.
Alle Pakete SOLLTEN grundsätzlich alle BRP-Skripte ausführen, aber manchmal ist es notwendig, dass ein Paket bestimmte Skripte deaktiviert. Es ist möglich, jedes BRP-Skript zu deaktivieren, indem die entsprechende Variable auf %{nil} gesetzt wird. So können Sie beispielsweise das Skript brp-python-bytecompile deaktivieren:
# Turn off Python bytecode compilation because this is a Jython
# package and we will generate JVM bytecode instead
%global __brp_python_bytecompile %{nil}
Jedes Paket, das ein BRP-Skript auf diese Weise deaktiviert, MUSS den Grund in einem zugehörigen Kommentar angeben. Eine Liste der standardmäßig ausgeführten BRP-Skripte erhalten Sie mit folgendem Befehl:
sed -r -n '/^%.?__os_install_post/,/%.?nil/p' /usr/lib/rpm/redhat/macros
Eine Liste aller BRP-Skripte erhalten Sie mit folgendem Aufruf:
rpmbuild --eval '%dump' |& grep ': __brp_'
Beseitigung häufiger Ursachen für nicht reproduzierbare Bauvorgänge
Eines der standardmäßig aufgerufenen BRP-Skripte ist %__os_install_post_build_reproducibility. Es dient der Normalisierung installierter Dateien, indem unerwünschte eingebettete Metadaten entfernt werden, die von der Bauumgebung abhängen und dazu führen können, dass unterschiedliche Bauvorgänge aus denselben Quellen nicht reproduzierbar sind.
In /usr/lib/rpm/macros.d/macros.build-reproducibility finden Sie Details darüber, wie dies eingerichtet werden kann.
Paketierung für EPEL
Diese Richtlinien und die unten stehenden anwendungsspezifischen Richtlinien decken größtenteils die Paketierung für sowohl Fedora als auch EPEL ab. Es gibt jedoch notwendigerweise einige Unterschiede. Für die Paketierung für EPEL lesen Sie bitte zusätzlich die EPEL-Paketierungsrichtlinien, um weitere Informationen zu erhalten.
Domain-spezifische Richtlinien
Für einige Anwendungen, Sprachen und Build-Systeme gibt es spezifische Richtlinien, die auf eigenen Seiten zu finden sind:
Want to help? Learn how to contribute to Fedora Docs ›