openSUSE:Paketbau Perl

Wechseln zu: Navigation, Suche
Der Paketbau Perl ist eine Schritt für Schritt Einführung, wie man Software-Pakete in Perl für openSUSE und andere unter Verwendung des openSUSE Build Service baut.


Bauwerkzeuge

cpanspec

cpanspec ist wahrscheinlich das beste Werkzeug, um ein CPAN-Paket in den openSUSE Build Service zu bringen. Das ist eine Paketbau-Beispielprozedur des Perl-Modules File::LibMagic für die Bauunterstützung.

# add devel:languages:perl
zypper ar http://download.opensuse.org/repositories/devel:/languages:/perl/openSUSE_11.2/devel:languages:perl.repo
zypper in cpanspec

cd your_checked_out_build_service_project
osc mkpac perl-File-LibMagic
cd perl-File-LibMagic

cpanspec -v File::LibMagic
osc build --local
# vi *.spec
...
 BuildRequires: perl(Other::Package)
 BuildRequires: libfile-devel
ZZ
osc ci

cpanspec wird das Tar-Archiv von SPAN herunter laden, es analysieren und eine Perl-Datei LibMagic.spec und eine Datei *.changes erzeugen. cpanspec wird aktiv unter devel:languages:perl gewartet.

Im Gegensatz zur Fedora-Version auf [1] wurde diese an den Bedarf unseres Build Service angepasst.

cpanspec_obs

Ein zusätzliches Verpackungs-Skript steht für die komplette Automatisierung einfacher Fälle zur Verfügung. Die einzigen Anforderungen sind, dass Sie zu einem Abmelde-Verzeichnis des OBS-Projektes navigieren, wo Sie ein neues Perl-Paket einreichen wollen, dann rufen Sie cpansec_cobs mit der exakten CPAN-Bezeichnung auf, gefolgt von einem OSC-Commit-Aufruf.

cpan2spec

Ist eine Fehlbezeichnung. Die Leite sagen 'cpan2spec', wenn sie 'cpanspec' meinen. Siehe oben.

cpan2dist

Die Bearbeitung von Spezifikationsdateien für den Paketbau von Perl-Modulen wird mit cpan2dist vereinfacht. Es kommt verbunden mit perl-5.10.0 und Aktualisierungen sind auf CPAN verfügbar und wird auf github entwickelt.

Das ist ein Beispielprozess, wie man das Perl-Modul File::LibMagic für den Bauservice packt:

# add devel:languages:perl
zypper ar http://download.opensuse.org/repositories/devel:/languages:/perl/openSUSE_11.2/devel:languages:perl.repo
zypper in perl-CPANPLUS-Dist-RPM
zypper in perl-CPANPLUS-Dist-SUSE
cd your_checked_out_build_service_project
osc mkpac perl-File-LibMagic
cd perl-File-LibMagic
cpan2dist --format CPANPLUS::Dist::SUSE File::LibMagic
osc vc perl-File-LibMagic
osc add File-LibMagic*.tar.* perl-File-LibMagic.{changes,spec}
osc build --local-package
# vi *.spec
osc ci

Mit Version 0.01 von CPANPLUS::Dist::SUSE, benötigen folgende Punkte unsere Aufmerksamkeit:

  • Gruppe sollte sein: Development/Libraries/Perl (fast gut, "/Perl" wird vermisst).
  • BuildRequires: für nicht-Perl Pakete (typisch *-devel) wird vermisst.
  • Requires: für Perl Pakete wird oft vermisst. Prüfe Makefile.PL
  •  %install Abschnitt sollte nicht rm -rf %{buildroot} machen
  •  %install berührt ein leeres %{buildroot}/%{_mandir}/man3/*.3pm.gz
  •  %install Abschnitt hat keine %perl_process_packlist
  •  %install Abschnitt hat keie %perl_gen_filelist
  •  %files Abschnitt sollte %files -f %{name}.files verwenden
  •  %bcond_with test
    %if %{with test}
    um optional einen langsamen Test-Abschnitt zu machen. (osc build --with test)
  •  %description: keine Beschreibung gefunden
  • License: GPL or GPLv2 or GPLv3

Eine inoffizielle Version steht zur Verfügung bei devel:languages:perl, die das Meiste von oben behebt. Es fügt auch einige BuildRequires hinzu: und als Experiment folgendes:

BuildRecommends: perl(Test::CheckManifest)

Das verursacht keinen Fehler, aber der Autor hat niemals gesehen, dass es jemals Test::CheckManifest herein zieht. Wie sollte ein Requires: tag geschrieben werden, wenn es zur Bauzeit benötigt wird?

Anstelle des Hinzufügens eines Tar-Archives könnte ein Service-Link verwendet werden, der den CPAN-URL des Tar-Archivs enthält, verwendet werden. Siehe devel:languages:perl:CPAN bezüglich weiterer Beispiele.

Welche Lizenz ist für Perl-Module zu verwenden

Die große Mehrheit der Perl-Module enthalten eine kurze Notiz zu Lizenzbedingungen am Ende der REACME-Datei. Manchmal gibt es auch eine Datei LICENSE oder COPYING im Paket. Wenn ein Perl-Modul eine Lizenz: "under the same terms as Perl itself" trägt (was gewöhnlich der Fall ist), dann sollte man in der Spezifikationsdatei %License lesen:

License: Artistic-1.0 or GPL-1.0+

Wenn die Lizenz nicht "unter den gleichen Bedingungen wie Perl selbst" steht, dann wählen Sie die passende Spezifikationsdatei-Syntax %License aus en:openSUSE:Accepted_licences#Good_Licenses (die Kategorie der Kurzbezeichnungen liefert die Zeichenkette die in die Spezifikationsdatei übernommen werden sollte). Kompliziertere Lizenzszenarios stehen unter: Die Fedora Lizenzrichtlinien für Paketbauer zur Verfügung.

RPM_Makros für Perl-Module

(aus: en:openSUSE:Packaging Conventions RPM Macros)

%if 0%{?suse_version} < 1120 
BuildRequires: perl-macros 
%endif

Fügen Sie die obigen BuildRequires hinzu, wenn Sie folgende Fehlermeldung erhalten:

+ %perl_gen_filelist
/var/tmp/rpm-tmp.6091: line 40: fg: no job control

%perl_archlib

Viele Perl-Pakete sind reines Perl. Sie können ohne Architektur (noarch) gebaut werden. Wenn möglich, fügen Sie dieses zu Ihrer Spezifikationsdatei hinzu:

 BuildArch: noarch

Andererseits ist  %perl_archlib hilfreich. Dieses Makro wird durch den Pfad, wo die Architektur spezifischen Teile von Perl installiert sind, ersetzt, zum Beispiel: /usr/lib/perl5/5.8.5/i586-linux-thread-multi.

Er wird normaler Weise durch das Paket perl selbst verwendet und vom Makro %perl_process_packlist. Siehe unten.

%perl_make_install

Dieses Makro führt einen make install Aufruf korrekt an verschiedenen Produkten aus. Vor SL 9.0 war der normale Weg, um es aufzurufen:


make PREFIX=$RPM_BUILD_ROOT/%_prefix \
INSTALLMAN1DIR=$RPM_BUILD_ROOT/%_mandir/man1 \
INSTALLMAN3DIR=$RPM_BUILD_ROOT/%_mandir/man3 \
install

Für 9.0 und spätere Versionen:

make DESTDIR=$RPM_BUILD_ROOT install_vendor

Mit dem Makro %perl_make_install wird das korrekt entsprechend der Version ausgeführt.

Dieses Beispiel stammt aus dem Paket perl-URI:

%install
%perl_make_install

%perl_process_packlist

Dieses Makro bereitet einige Dateien, die mit Perl-Modulen verbunden sind, für das endgültige Paket vor. Das führt die folgenden Aktionen aus:

  • Löschen von $RPM_BUILD_ROOT aus %perl_archlib/perllocal.pod und umbenennen der Datei zu einer Paket spezifischen Datei. Unten finden Sie detailliertere Informationen.
  • Suche nach den installierten Dateien .packlist und löschen von $RPM_BUILD_ROOT daraus.

Jedes Paket, das ein Perl-Modul enthält, sollte dieses Makro im Abschnitt %install aufrufen.

Die Datei %perl_archlib/perllocal.pod muss umbenannt werden, weil es Informationen über die zusätzlich installierten Perl-Module enthält und offensichtlich nicht an der gleichen Stelle von mehreren Paketen installiert werden kann. Darum wird es umbenannt und ein spezielles Modul SuSEconfig /sbin/conf.d/SuSEconfig.perl fügt diese Information zum System %perl_archlib/perllocal.pod hinzu, nachdem das Paket installiert wurde.

Dieses Beispiel wurde aus dem Paket perl_URI: entnommen:

%install
%perl_make_install
%perl_process_packlist

%files
[...]
/var/adm/perl-modules/%{name}

%perl_gen_filelist

Seit 11.2 (oder mit BuildRequires: perl-macros), kann mehr Automatismus erreicht werden, so:

%install
%perl_make_install
%perl_process_packlist
%perl_gen_filelist

%files -f %{name}.files
%defattr(-,root,root,-)
%doc README CHANGES COPYING


Beachten Sie, dass dieses Makro kann keine Dateien erkennen, die nicht installiert wurden. Daher verwenden wir noch %doc, um wichtige Dateien direkt aus dem Quellbaum zu sammeln.

%perl_sitearch

Dieses Makro wird durch den Pfad, in dem die Architektur spezifischen Teile der Perl-Module installiert sind, von einem lokalen Administrator (/usr/lib/perl5/site_perl/5.8.5/i586-linux-thread-multi) ersetzt. Die Pakete, die mit SUSE Linux veröffentlicht werden, verwenden stattdessen den Pfad, der von %perl_vendorarch definiert wird. Siehe unten.

%perl_sitelib

Dieses Makro wird durch den Pfad ersetzt, bei dem die Architektur unabhängigen Teile der Perl-Module von einem lokalen Administrator (/usr/lib/perl5/site_perl/5.8.5) installiert werden. Die Pakete, die mit SUSE Linux veröffentlicht werden verwenden den Pfad, der statt dessen durch %perl_vendorlib definiert ist (siehe unten).

%perl_vendorarch

Dieses Makro wird durch den Pfad ersetzt, bei dem die Architektur spezifischen Teile der Perl-Module durch einen Linux-Anbieter (/usr/lib/perl5/vendor_perl/5.8.5/i586-linux-thread-multi) installiert werden. Das Makro wird typischer Weise in der Dateiliste verwendet. Das Beispiel stammt aus dem Paket perl-URI:

%files
[...]
%{perl_vendorarch}/auto/URI

Dieser Pfad wurde seit SL 9.0 verwendet. Bis dahin wurden die Perl-Module unter /usr/lib/perl5/site_perl unter Verwendung des Makros %perl_sitearch installiert. Das Verzeichnis site_perl ist nun für Module vorgesehen, die von einem lokalen Administrator (siehe oben bei %perl_sitearch) installiert werden.

%perl_vendorlib

Dieses Makro ersetzt den Pfad, in dem Architektur unabhängige Teile der Perl-Module von Linux-Anbietern (/usr/lib/perl5/vendor_perl/5.8.5) installiert werden. Das Makro wird typischer Weise in der Dateiliste verwendet. Dieses Beispiel stammt aus dem Paket perl-URI:

%files
[...]
%{perl_vendorlib}/URI.pm
%{perl_vendorlib}/URI

Dieser Pfad wurde seit SL 9.0 verwendet. Bis dahin wurden Perl-Module unter /usr/lib/perl5/site_perl installiert, unter Verwendung des Makros %perl_sitearch. Das Verzeichnis site_perl ist nun für Module vorgesehen, die von dem lokalen Administrator (siehe oben bei %perl_sitelib) installiert werden.

%perl_version

Diese Makro wird ersetzt durch eine Version von Perl, die zum Bau des Paketes verwendet wird, so 5.8.5. Es wird in Paketen verwendet, die ein Perl-Modul unterstützen, um die Abhängigkeit von Perl zu definieren.

In älteren Paketquellen wurde es typischer Weise folgen der Weise verwendet:

Requires:     perl = %{perl_version}            # deprecated, use %perl_requires

%perl_requires

Seit 11.4 sollten die Anforderungen für die gegenwärtige Perl-Version als:

%if 0%{?suse_version} < 1140
Requires:     perl = %{perl_version}
%else
%{perl_requires}
%endif

geschrieben werden. Vor 11.4 benötigen wir ausdrücklich 'Requires' unter Verwendung des Makros  %perl_version.

Bitte beachten Sie, dass quilt nicht länger auf 11.3 funktioniert, wenn man dieses Makro verwendet.

%__perl

Die Bezeichnung des Perl, das auf dem System installiert ist.

%perl_gen_filelist

Erzeugt %[name}. Dateien, die eine Liste von Dateien enthalten, die in %{buildroot} installiert sind. Das kann später zur Vereinfachung des Abschnitts  %files verwendet werden. Rufen Sie dieses am Ende Ihres Abschnitts %install auf:

 %install
 [...]
 %perl_process_packlist
 %perl_gen_filelist

Beachten Sie, dass dieses Makro keine Dateien erkennen kann, die nicht installiert sind. Daher verwenden wir noch  %doc, um die wichtigen Dateien direkt aus dem Quellbaum zu sammeln. Ihr Abschnitt %files könnte so einfach wie dieses sein:

 %files -f %{name}.files
 %defattr(-, root, root, -)
 %doc Changes README COPYING

Das hilft, wenn Ihr %{perl_vendorarc}/* Batzen ebenso das Verzeichnis '*/auto' enthält. Und seinen Ausschlusses auszudrücken, würde eine komplexe Liste von anderen globalen Strukturen erfordern. Siehe das Beispiel unten.

Probleme mit rpmlint

Das Verzeichnis auto directory ist enthalten

Den Bau bricht ab mit

... starten von 04-check-filelist
... checking filelist
Perl-Datei-MMagic-XS: Verzeichnis auto ist im Perlpaket enthalten 

Das kann man typischer Weise sehen, wenn die Spezifikationsdatei enthält

%files
[...]
%{perl_vendorlib}/*

Es würde für die Spezifikationsdateien der Standard sein, die mit cpan2dist von Perl-5.10.0 erzeugt werden. Dieser Batzen enthält  %{perl_vendorlib}/i586-linux-thread-multi/auto, wenn Ihr Paket einige Bibliotheken *.so enthält. Es darf nicht das Verzeichnis '*/auto' selbst enthalten, nur den Inhalt und die Unterverzeichnisse.

%files
[...]
%{perl_vendorlib}/*/auto/*
%{perl_vendorlib}/*/File
%{perl_vendorlib}/*/File/*

Das könnte für ein Modul File::* funktionieren. Betrachten Sie oben %perl_gen_filelist als eine wahrscheinlich bessere Lösung.

Das Verlinken schlägt Fehl mit: undefinierter Bezug zur "Funktionsbezeichnung"

Wenn Sie den Fehler erhalten, dass Sie undefinierte Bezüge haben, aber die benötigten Bibliotheken sind definiert, bedeutet das, dass die Verlinkungsordnung nicht richtig ist. Alle Bibliotheken in openSUSE >11.0 sind mit der ld flag --as-needed verlinkt. Schauen wir uns ein Beispiel an:

Angenommen, dass Sie eine statische Bibliothek libwurst bauen und sie verwendet die Funktion pow() aus der Mathematik-Bibliothek.

 $ gcc -Wl,--as-needed --static main.c -o wurstsalat -L. -lm -lwurst
 ./libwurst.a(wurst.o): In function `wurst':
 wurst.c:(.text+0x29): undefined reference to `pow'

Das Problem hier ist, dass der Linker keinen Bezug zu pow() in main.c findet. Denn die erste Bibliothek ist libm. Da sie nicht benötigt wird, läßt der Linker sie aus. Sie haben gegen libwurst.a zu verlinken, bevor Sie gegen libm verlinken.

 $ gcc -Wl,--as-needed --static main.c -o wurstsalat -L. -lwurst -lm

Zusammengefasst: Wenn man --as-needed verwendet, ist die Reihenfolge, in der die Bibliotheken in der Kommandozeile erscheinen, relevant: jede Bibliothek X muss allen Bibliotheken Y vorangehen, die Symbole anbieten die X verwenden.

Wenn Ihr Paket zu komplex ist oder sie haben wenig Erfahrung mit dem Patchen, fügen Sie in Ihrem Abschnitt %build hinzu:

 export SUSE_ASNEEDED=0

Das wird den Teil mit --as-needed ebenso auslassen.

Weitere Informationen finden Sie unter http://www.gentoo.org/proj/en/qa/asneeded.xml#doc_chap2