Paketbaurichtlinien für Perl

Benennung von Modulpaketen

Besitz von Verzeichnissen

Wie in den allgemeinen Paketbaurichtlinien angegeben, wird von Perl-Paketen erwartet, dass sie sich die Besitzrechte an bestimmten Verzeichnissen teilen.

Im Allgemeinen muss ein architekturunabhängiges Perl-Paket Folgendes besitzen:

# Für noarch-Pakete: vendorlib
%{perl_vendorlib}/*

…​und ein architekturspezifisches Perl-Paket muss Folgendes besitzen:

# For arch-specific packages: vendorarch
%{perl_vendorarch}/*
%exclude %dir %{perl_vendorarch}/auto/

Bauabhängigkeiten

Wie hier beschrieben, muss ein Paket seine Bauabhängigkeiten (mittels BuildRequires:) außerhalb des minimalen Satzes, der für die Erstellung von RPM-Paketen erforderlich ist, explizit angeben. Dies schließt jegliche Abhängigkeit von Perl ein. Obwohl Perl möglicherweise einmal im Standard-Buildroot enthalten war, ist dies aktuell nicht mehr der Fall.

Nachfolgend finden Sie eine Liste der Perl-bezogenen Bauabhängigkeiten, die Sie möglicherweise benötigen.

  • perl-generators – Generiert automatisch Laufzeit-„Requires“ und -„Provides“ für installierte Perl-Dateien. Bei jeder Installation eines Perl-Skripts oder Perl-Moduls muss dieses Paket als Bauabhängigkeit angegeben werden.

  • perl-interpreter – Der Perl-Interpreter muss als Bauabhängigkeit aufgeführt werden, wenn er in irgendeiner Weise aufgerufen wird, entweder explizit über perl oder %__perl oder als Teil des Bausystems Ihres Pakets.

  • perl-devel – Stellt Perl-Headerdateien bereit. Wenn Sie architekturspezifischen Code erstellen, der gegen die Bibliothek libperl.so verlinkt ist (z.B. ein XS-Perl-Modul), müssen Sie BuildRequires: perl-devel einbinden.

Wird für den Bau ein bestimmtes Perl-Modul benötigt, verwenden Sie die Syntax perl(MODULE), wie oben beschrieben. Dies gilt auch für sogenannte Kern-Module, da diese im Laufe der Zeit in das Perl-Basispaket aufgenommen oder daraus entfernt werden können.

Wenn Sie Ihr Paket auf eine bestimmte Perl-Version beschränken müssen, verwenden Sie die Abhängigkeit perl(:VERSION) mit der gewünschten Versionsbeschränkung (z. B. perl(:VERSION) >= 5.22). Vergleichen Sie die Version nicht mit der Version des Pakets perl, da diese eine Epochennummer enthält, was Versionsvergleiche erschwert.

Requires und Provides für Perl

Perl-Pakete verwenden die virtuelle Namenskonvention perl(Foo), um ein bestimmtes Perl-Modul zu kennzeichnen. Pakete sollten dies verwenden und den Paketnamen nicht direkt einbinden. Beispielsweise sollte ein Paket, das das Perl-Modul Readonly benötigt, nicht explizit perl-Readonly einbinden, sondern perl(Readonly), das vom Paket perl-Readonly bereitgestellt wird.

Es wird empfohlen, explizite Abhängigkeiten für Kernmodule anzugeben, da diese zwischen Teilpaketen verschoben werden oder aus dem Perl-Kern verschwinden können.

Versioniertes MODULE_COMPAT_ Requires oder perl-libs

Pakete, deren Perl-Module in %{perl_vendorarch}, %{perl_vendorlib}, %{perl_privlib} oder %{perl_archlib} installiert sind, erhalten automatisch eine Abhängigkeit von perl-libs für reine Perl-Module oder eine Abhängigkeit von perl(:MODULE_COMPAT_<perl_version>) für Bibliotheken mit kompiliertem Code. Die Abhängigkeit wird von perl-generators verwaltet.

Pakete, die den Perl-Interpreter oder libperl.so benötigen, aber keine Module in die oben genannten Verzeichnisse installieren oder explizit auf libperl.so.<perl_version> verlinken, müssen die Abhängigkeit manuell behandeln.

Filtern von „Requires“ und „Provides“

Der Abhängigkeitsgenerator von RPM fügt oft zusätzliche Abhängigkeiten hinzu und geht fälschlicherweise davon aus, dass Pakete Funktionen bereitstellen, die gar nicht der Realität entsprechen. Um dies zu beheben, muss der Abhängigkeitsgenerator außer Kraft gesetzt werden, damit die zusätzlichen Abhängigkeiten herausgefiltert werden können. Weitere Informationen finden Sie hier.

Manuelle Requires und Provides

Unter bestimmten Umständen kann der automatische Abhängigkeitsgenerator von RPM Abhängigkeiten übersehen, die hinzugefügt werden sollten. Dies liegt üblicherweise an der Verwendung von Sprachkonstrukten, die das Abhängigkeitsskript nicht erwartet hat. Ein Beispiel hierfür findet sich im Paket perl-Class-Accessor-Chained, wo Folgendes zu finden ist:

use base 'Class::Accessor::Fast';
...
use base 'Class::Accessor';

Ein deutliches Anzeichen für diese spezielle Konstruktion ist, dass das Paket eine Abhängigkeit von perl(base) enthält. Dies ist jedoch nicht die einzige Situation, in der Abhängigkeiten fehlen können. Dieses Paket benötigte folgende zusätzliche Abhängigkeiten:

Requires: perl(Class::Accessor), perl(Class::Accessor::Fast)

Generell empfiehlt es sich, die Dokumentation des Upstream-Pakets zu lesen, um Einzelheiten zu weiteren Abhängigkeiten zu erfahren.

Ein weiteres ähnliches Beispiel für fehlende Abhängigkeiten findet sich in perl-Spreadsheet-WriteExcel:

package Spreadsheet::WriteExcel::Utility;
...
use autouse 'Date::Calc'  => qw(Delta_DHMS Decode_Date_EU Decode_Date_US);
use autouse 'Date::Manip' => qw(ParseDate Date_Init);

Ebenso kann es vorkommen, dass „Provides:“ fehlt, wie es in Bug #167797 der Fall war, wo das Paket perl-DBD-Pg aufgrund des folgenden Konstrukts in DBD::Pg Version 1.43 nicht perl(DBD::Pg) bereitstellen konnte:

{ package DBD::Pg;

Die übliche Schreibweise, die auch von RPM erwartet wird, ist:

{
package DBD::Pg;

Daher ist es ratsam, die „Provides:“-Dateien Ihrer Pakete zu überprüfen, um sicherzustellen, dass sie korrekt und vollständig sind. Fehlt etwas, kann dies entweder durch manuelle „Provides:“-Einträge oder durch Patchen des Quellcodes in ein von RPM korrekt verarbeitbares Format behoben werden.

URL-Tag

Bei CPAN-basierten Paketen sollte der URL-Tag eine nicht versionierte metacpan.org-URL verwenden. Wenn man beispielsweise das Modul Net::XMPP paketieren würde, sähe die URL so aus:

URL: https://metacpan.org/release/Net-XMPP

Testen und Test-Suites

Perl-Pakete verfügen typischerweise über eine umfangreiche und aussagekräftige Testsuite. Es ist üblich, so viele Tests wie möglich auszuführen, vorbehaltlich der technischen Beschränkungen des Bausystems. Dies bedeutet mindestens:

  • Alle für die Tests benötigten Module sollten als BuildRequires aufgeführt werden

  • Alle „optionalen“ Tests sollten aktiviert werden

  • Alle für die Tests benötigten, aber noch nicht in Fedora enthaltenen Module, die in Fedora integriert werden könnten, sollten ebenfalls zum Review eingereicht werden

Wann nicht getestet werden sollte

Hierbei sind ein paar Einschränkungen zu beachten:

  • Optionale Tests müssen nicht aktiviert werden, wenn sie zu zirkularen Bauabhängigkeiten führen

  • Tests, die Netzwerk- oder Bildschirmzugriff benötigen, sollten für das Bausystem deaktiviert werden, jedoch mit einer entsprechenden Methode für lokale Bauvorgänge

  • Tests, die die Funktionalität des Pakets nicht prüfen, sollten zwar aufgerufen werden, ihr Ausschluss sollte jedoch nicht als Hindernis angesehen werden (z.B. Test::Pod::Coverage, Test::Kwalitee und dergleichen)

  • Autoren-, Release-Candidate- oder Smoke-Tests müssen nicht aktiviert werden, z. B. Tests mit Perl::Critic.

Darüber hinaus ist es bei „Meta“-Paketen, die eine gemeinsame Schnittstelle für mehrere ähnliche Module bereitstellen, nicht notwendig, alle unterstützten Module zu paketieren, solange mindestens ein Modul existiert, das die Funktionalität des Meta-Pakets ermöglicht. Beispielsweise bietet das Paket perl-JSON-Any (JSON::Any) eine gemeinsame Schnittstelle für JSON, JSON::XS, JSON::PC, JSON::Syck und JSON::DWIM. JSON::PC und JSON::DWIM sind derzeit nicht in Fedora enthalten und müssen daher nicht paketiert werden, da beispielsweise JSON::XS JSON::Any aktiviert.

Bedingtes Aktivieren oder Deaktivieren von Tests

Eine gängige Methode, einen Test zwar für Mock zu deaktivieren, ihn aber lokal zu aktivieren, besteht darin, einen _with_foo-Makrotest zu verwenden, z.B.

%check
%{!?_with_network_tests: rm t/roster.t }
./Build test

Mit diesem Konstrukt wird ein fehlerhafter Test entfernt und nicht ausgeführt, es sei denn, --with network_tests wird an rpmbuild übergeben oder %_with_network_tests ist irgendwo definiert, z.B. in der $HOME/.rpmmacros-Datei des Benutzers. Dieser Ansatz erhält die Testsuite für lokale Bauvorgänge und berücksichtigt gleichzeitig die technischen Beschränkungen des Bausystems.

Makefile.PL vs Build.PL

Perl-Module verwenden typischerweise eines von zwei verschiedenen Bausystemen:

  • ExtUtils::MakeMaker

  • Module::Build

Die beiden unterschiedlichen Stile sind leicht erkennbar: ExtUtils::MakeMaker verwendet die Build-Datei Makefile.PL und ist der „klassische“ Ansatz; Module::Build ist ein neuerer Ansatz mit Unterstützung für Funktionen, die MakeMaker nicht bietet. Die endgültige Entscheidung für das System liegt zwar beim jeweiligen Entwickler, aber wenn Build.PL in einer Distribution vorhanden ist, sollte der Paketierer dieses Build-Framework verwenden, sofern kein triftiger Grund dagegen spricht.

Siehe auch PackagingTips/Perl#Makefile.PL_vs_Build.PL .

.h-Dateien in Modulpaketen

Es ist nicht ungewöhnlich, dass Binärmodulpakete .h-Dateien enthalten, siehe z.B. perl-DBI, perl-Glib, perl-Gtk2. Aus verschiedenen Gründen sollten diese nicht in ein -devel-Paket ausgelagert werden.

Aktualisierungen von Paketen

Eine Zusammenfassung der für die Aktualisierungen verwendeten Werkzeuge sowie hilfreiche Kommentare finden Sie hier: Perl/updates.

Nützliche Tipps

Manche Module versuchen, Module aus dem CPAN einzubinden. Anstatt das Makefile zu patchen, können Sie einfach PERL5_CPANPLUS_IS_RUNNING=1 hinzufügen, um das CPAN vollständig zu umgehen.

Perl-SIG

Leute aus dem Perl-Umfeld, die Pakete erstellen, pflegen und überprüfen. Wenn Sie sich für Perl interessieren, abonnieren Sie die Mailingliste, wo aktuelle Themen diskutiert werden.