openSUSE:Paketbau von Python-Software
Inhaltsverzeichnis
Der schnelle und automatische Weg
Lassen wir uns annehmen, Sie wollen zope.interface packen und wissen nicht wie ist die Software exakt bezeichnet oder woher man sie herunterladen kann. Als erstes können Sie danach suchen und laden das Quell-Tar-Archiv automatisch herunter, wenn Sie das richtige Modul gefunden haben:
$ py2pack search zope.interface suchen nach dem Modul zope.interface... gefunden zope.interface-3.6.1 $ py2pack fetch zope.interface herunterladen des Paketes zope.interface-3.6.1... von http://pypi.python.org/packages/source/z/zope.interface/zope.interface-3.6.1.tar.gz
Als nächsten Schritt wollen Sie ein Paketrezept für Ihre Distribution erzeugen. Für auf RPM basierende Distributionen wollen Sie eine Spezifikationsdatei mit der Bezeichnung python-zopeinterface.spec erstellen:
$ py2pack generate zope.interface -t opensuse.spec -f python-zopeinterface.spec
Das Quell-Tar-Archiv und das Paketrezept ist alles was Sie brauchen, um die RPM-Datei zu erstellen. Der letzte Schritt kann davon abhängen, welche Distribution Sie verwenden. Noch einmal, für openSUSE (unt unter Verwendung des Open Build Service) wird das komplette Rezept:
$ osc mkpac python-zopeinterface $ cd python-zopeinterface $ py2pack fetch zope.interface $ py2pack generate zope.interface -f python-zopeinterface.spec $ osc build $ osc vc $ osc commit
Die erste Zeile verwendet osc, das Build Service Kommandozeilenwerkzeug, um ein neues Paket zu erzeugen (wünschenswert in Ihrem Build Service home project). Die py2pack Schritte sind bereits bekannt. Schließlich wird das Paket getestet (gebaut lokal), eine Wechsel-Datei (package changelog) wird erzeugt (mit ‘osc vc’) und das Ergebnis wird zum Build Service für den allgemeinen Bedarf zurückgesendet. Abhängig vom Python-Modul, könnte es sein, dass Sie die erzeugte Spezifikationsdatei ein klein wenig anpassen müssen.
Viele Pakete verwenden die python setuptools. In diesem Fall muss die Spezifikationsdatei um ein
BuildRequires: python-setuptools
ergänzt werden. Der entsprechende Aufruf von python setup.py in den Sektionen %build und %install wird hingegen automatisch erstellt.
Py2pack ist ganz clever und versucht, so viel wie möglich automatisch zu erstellen. Aber es hängt von den Metadaten ab, die das Modul unterstützt. So können schlechte Metadaten zu mittelmäßigen Ergebnissen führen. Um weitere Hilfe zur Verwendung von py2pack zu erhalten, führen Sie folgendes Kommando aus:
$ py2pack help
Hinweise, wie man Python-Module manuell packt
Der einfachste Fall
Hier ist ein einfaches Beispiel für eine Spezifikationsdatei (vom Paket python-Jinja2). Sie werden wahrscheinlich nicht abhängen von 'python-distribute'
# # Spezifikationsdatei für das Paket python-Jinja2 # # Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. # # Alle Modifizierungen und Ergänzungen zu der Datei, die von dritter Seite beigetragen wird # bleibt das Eigentum ihrer Copyright-Besitzer, außer es ist darüber anders verewinbart. # Die Lizenz für diese Datei, Modifikationen und Ergänzungen zu der Datei # ist die gleiche Lizenz wie für das unveränderte Paket selbst (außer die # Lizenz für das unveränderte Paket ist keine Open Source Lizenz, in diesem # Fall ist die Lizenz die MIT Lizenz). Eine "Open Source Lizenz" ist eine # Lizenz, die mit der Open Source Definition (Version 1.9) konform ist und # von der Open Source Initiative veröffentlicht wird. # Bitte reichen Sie Fehlerbereinigungen oder Kommentare via http://bugs.opensuse.org/ # ein. Name: python-Jinja2 Version: 2.6 Release: 0 Summary: Eine schnelle und leicht zu verwendende Vorlagen-Maschine, geschrieben in Python License: BSD-3-Clause Group: Development/Languages/Python Url: http://jinja.pocoo.org/ Source: http://pypi.python.org/packages/source/J/Jinja2/Jinja2-%{version}.tar.gz BuildRequires: fdupes BuildRequires: python-devel BuildRequires: python-distribute Provides: python-jinja2 = %{version} Obsoletes: python-jinja2 < %{version} BuildRoot: %{_tmppath}/%{name}-%{version}-build %if 0%{?suse_version} && 0%{?suse_version} <= 1110 %{!?python_sitelib: %global python_sitelib %(python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} %else BuildArch: noarch %endif %description Jinja2 ist eine Vorlagen-Maschine, geschrieben in reinem Python. Sie unterstützt eine von Django angeregte nicht-XML Syntax aber unterstützt Inline-Ausdrücke und optional eine Sandbox-Umgebung. %package vim Summary: Jinja2 syntax files for Vim License: BSD-3-Clause Group: Productivity/Text/Editors Requires: %{name} = %{version} %description vim Vim Syntax hervorhebendes Schema für Jinja2 Vorlagen. %package emacs Summary: Jinja2 syntax files for Emacs License: GPL-2.0+ Group: Productivity/Text/Editors Requires: %{name} = %{version} %description emacs Emacs Syntax hervorhebendes Schema für Jinja2 Vorlagen. %prep %setup -q -n Jinja2-%{version} %build python setup.py build sed -i 's/\r$//' LICENSE # Fix wrong EOL encoding %install python setup.py install --prefix=%{_prefix} --root=%{buildroot} install -Dm644 ext/Vim/jinja.vim %{buildroot}%{_datadir}/vim/site/syntax/jinja.vim # Install VIM syntax file install -Dm644 ext/jinja.el %{buildroot}%{_datadir}/emacs/site-lisp/jinja.el # Install Emacs syntax file %if 0%{?suse_version} > 1010 %fdupes %{buildroot}%{_prefix} %endif %files %defattr(-,root,root,-) %doc AUTHORS CHANGES LICENSE artwork examples ext/JinjaTemplates.tmbundle.tar.gz %{python_sitelib}/* %files vim %defattr(-,root,root,-) %{_datadir}/vim %files emacs %defattr(-,root,root,-) %{_datadir}/emacs/site-lisp/jinja.el %changelog
Bezeichnungsgrundsatz
SUSE hat eine Richtlinie zur Bezeichnung von Paketen für Python-Module. Ein Modul ist für Python, was was für C gemeinsam benutzte Bibliotheken sind - Ein Stück Code, der nicht selbständig funktioniert, aber die Funktionsfähigkeit für andere Python-Programme unterstützt.
Alle Python-Modul-Pakete, ob reines Python oder C-basierend, sollten als python-Modul-Bezeichnung aufgerufen werden. Der Bauprozess prüft danach und gibt eine Warnung aus, ob er eine Python-Datei in einem Paket findet, die nicht auf diese Weise bezeichnet wurde.
Die Modul-Bezeichnung sollte die Bezeichnung des Verzeichnisses des Moduls in site-packages sein. (Technisch gesehen, eine Bezeichnung unter der Sie dieses Modul in Python importieren.)
Dieser Grundsatz wird nicht auf Anwendungen für Endanwender angewendet - wenn Sie also etwas packen, das ein Icon im Anwendungsmenü haben wird, sollten Sie nur das Paket mit seiner normalen Bezeichnung aufrufen. Beachten Sie, dass viele solcher Anwendungen Teile von sich selbst in die Hierarchie site-packages von Python installieren, was die Warnung über diesen Bezeichnungsgrundsatz auslösen wird. In solch einem können Sie die Warnung sicher ignorieren.
Es gibt einige Grenzfälle. Was ist eine Anwendung und was ist ein Modul. Zum Beispiel kommen viele Module mit mit einfachen Kommandozeilen-Werkzeugen, die es Ihnen erlauben, eine Teilmenge ihres Funktionsumfangs direkt zu verwenden. Die Daumenregel dafür ist folgende: Wenn Sie glauben, dass der Anwender Ihr Paket installieren wird, indem es das Kommandozeilen-Werkzeug nutzt, rufen Sie es mit seinem normalen Namen auf. Wenn das Paket eine Abhängigkeit von einigen anderen Python-Anwendungen sein wird, wenden Sie bitte den Bezeichnungsgrundsatz an.
BuildRequires
Im einfachsten Fall verwenden Sie das Makro %py_requires.
Wenn Sie ein C Modul bauen, verwenden Sie %py_requires -d. Das zieht python-devel hinzu.
Wenn Sie es auf das am einfachsten mögliche BuildRequires abgesehen haben, dann werden Sie python-base manuell einbeziehen wollen und wahrscheinlich python-devel anstelle der Verwendung des Makros.
Einige Module benötigen zum Bau Einrichtungswerkzeuge. In diesem Fall fügen Sie das Paket python-setuptools (oder python-distribute) zu BuildRequires hinzu.
Python Version
In openSUSE, auch Versions-agnostische Python Pakete müssen von einer spezifischen Python-Reihe abhängen. Eine Python-Reihe wird durch eine Haupt- und untergeordneten Version gekennzeichnet. Zum Beispiel, die momentane Pythonreihe ist 2.7, die stabile Linie und 3.2 (Stand 26.05.2012) für py3k.
Das ist, weil Sie in Versions-spezifische Verzeichnisse /usr/lib(64)/pythonX.Y/site-packages installieren, in denen X.Y die Serie ist.
Das Makro %py_requires wir für Sie die korrekte Version fordern. Sie können auch Require: python-base = %py_ver verwenden.
Dateiablage
openSUSE ist so konfiguriert, dass die Dateien per Standard unter /usr/local abgelegt werden, indem sie automatische werkzeuge nachahmen. Wenn das Kommando install verwendet wird, müssen Sie --prefix=%{_prefix} spezifizieren, so dass das Paket in den richtigen /usr-Präfix installiert wird.
Alle Dateien mit Pythonquellen und Bytecode sollten in /usr/lib(64)/pythonX.Y/site-packages oder vielleicht /usr/lib(64)/yourapp abgelegt werden. Die FHS sagt, dass die Hierarchie /usr/share nur Daten enthalten sollten. Installieren Sie keine Quellen darin. Es ist keine strenge Forderung, sondern nur eine Empfehlung. Wenn der Upstream Ihres Paketes versucht unter /usr/share zu installieren, bitte versuchen Sie sie von ihrem Fehler zu überzeugen. Fühlen Sie sich nicht verpflichtet, die Pakete zu Tode zu patchen, nur um sie in /usr/lib zu installieren.
Dateilisten
Python für openSUSE definiert eine sehr brauchbare Erweiterung für ein Installationskommando:
--record-rpm=<filename> ist das Gleiche wie --record=<filename>,
aber es listet ebenso Verzeichnisse in ein RPM-kompatibles Format. Darum können Sie leicht das Folgende verwenden:
%install python setup.py install --prefix=%{_prefix} --root=$RPM_BUILD_ROOT --record-rpm=INSTALLED_FILES %files -f INSTALLED_FILES %defattr(-,root,root)
Hoffentlich werden wir es hinkriegen, diese Verbesserung upstream zu puschen.
Für den Fall, dass Sie wirklich Ihre Dateien per Hand spezifizieren müssen, gibt es zwei brauchbare Makros:
- %python_sitelib erweitert auf /usr/lib/pythonX.Y/site-packages. Das ist der Installationsort für Plattform unabhängige Module.
- %python_sitearch erweitert auf %{_libdir}/pythonX.Y/site-packages, das ist entwerder /usr/lib oder /usr/lib64, abhängig von Ihrer Architektur. Das ist der Installationsort für Plattform abhängige Module.
System-Architektur
Wenn Ihr Paket nur Python-Quellen (.py), Bytecode-Dateien (.pyc und .pyo) und Plattform unabhängige Daten enthält, sollten Sie es als noarch markieren. Beziehen Sie BuildArchitectures: noarch beim Start Ihrer Spezifikationsdatei ein. Solch ein Modul sollte vollständig in %python_sitelib installieren.
Ansonsten installiert das ganze Modul in %python_sitearch. Beachten Sie, dass es nicht möglich ist, ein Teil des Moduls in in %python_sitelib und den anderen Teil in %python_sitearch abzulegen. Und in den meisten Fällen, auch wenn ein Paket mehr als ein Modul enthält, sollten alle in einem Präfix sein.
Das ist wichtig, so dass wir es betonen müssen: Das ganze Modul ist entweder Plattform unabhängig oder es ist es nicht. Sogar eine Binärbibliothek oder eine Plattform spezifische Konfigurationsdatei in einem ansonsten reinen Python-Modul markiert das vollständige Modul als Plattform abhängig und Ihnen wird es nicht möglich sein, es als noarch zu verwenden. Das wird gewöhnlich von dem Paket distutils durchgeführt, so dass Sie sich nicht beunruhigen müssen.
Gewisse Pakete mögen Teile von sich selbst in %python_sitelib und Teile in %python_sitearch installieren. Derartige Einstellungen sind gewöhnlich die Ursache für Fehler und Probleme. Wenn Sie exakt wissen, was Sie machen, sollten Sie solche Pakete so modifizieren, dass alles in %python_sitearch landet.
Einrichtungswerkzeuge/Eier
In der Vergangenheit unterstützte Fedora die Eier für Upstream-Distributionen nur minimal. Da Eier weit mehr als Upstream angenommen werden, brauchen wir eine umfassendere Dokumentation, wie wir diese handhaben. Das Folgende ist eine Zusammenfassung der Richtlinien zur Durchsicht. Die komplette Strategie enthält Beispiele und Begründungen für die Art und Weise, wie wir diese Sachen durchführen.
- Muss: Python Eier müssen aus den Quellen gebaut werden. Man kann nicht einfach ein Ei von Upstream nehmen und es in ein passendes Verzeichnis ablegen.
- Muss: Python Eier dürfen keine Abhängigkeiten während des Bauprozesses herunterladen.
- Muss: Wenn Ei-Info-Dateien durch die Bau-Skripte des Moduls erzeugt werden, müssen sie in das Paket einbezogen werden.
- Muss: Wenn Sie ein compat Paket bauen, muss es installiert werden unter Verwendung von easy_install -m, damit es keinen Konflikt mit dem Hauptpaket auslöst.
- Muss: Wenn Sie mehrere Versionen bauen (für ein compat Paket), muss eines der Pakete eine Standardversion enthalten, damit es via "import MODULE" ohne vorherige Einstellung verwendbar ist.
- Sollte: Ein Paket, das von einem anderen Paket via eine Ei-Schnittstelle verwendet wird , sollte es eine Ei-info unterstützen.
Byte kompilierte Dateien
Python wird automatisch versuchen, Dateien byte zu kompilieren, wenn es läuft, um den Start beim nächsten Mal zu beschleunigen. Diese Dateien werden in Dateien mit den Erweiterungen .pyc (compiled python) oder .pyo (optimized compiled python) gespeichert. Diese Dateien sind Byte-Codes, die über Betriebssysteme portabel sind. Wenn Sie diese nicht in Ihre Pakete einbeziehen, wird Python versuchen, sie zu erzeugen, wenn der Benutzer das Programm verwendet. Wenn der Systemadministrator sie verwendet, dann werden die Dateien erfolgreich geschrieben. Später, wenn das Paket gelöscht wird, werden die Dateien mit .pyc und .pyo auf dem Dateisystem zurückgelassen. Um das zu verhindern, müssen Sie die Dateien Byte-kompilieren, wenn Sie Ihr Paket bauen, und die Dateien in die Sektion %files einbeziehen.
Viele Pakete installieren byte-kompilierte .pycs und .pyos selbst. Wenn Ihr Paket das nicht macht, sollten Sie %{py_compile} <directory> verwenden, um .pyc und %{py_compile -O} <directory> für .pyo Dateien zu erzeugen.
Meistens sind .pyo Dateien genau das Gleiche wie .pyc. Sie können Speicherplatz sparen, indem Sie fdupes laufen lassen, um sie hart zu zusammen zu verlinken.
BuildRequires: fdupes (...) %install (...) %fdupes $RPM_BUILD_ROOT%{py_sitedir}
Zusammenfassung brauchbarer RPM-Makros
- %py_ver - Python Serienbezeichnung (Haupt-.untergeordnete Versions-Nummer)
- %py_compile - Byte-kompilierte Python Quellen von dem spezifizierten Verzeichnis. Verwenden Sie %{py_compile -O}, um die Bytecode zu optimieren (.pyo)
- %py_requires - spezifiziert BuildRequires für den Python-Interpreter und Requires (aktuell PreReq) für die spezifische Python-Serie. Verwenden Sie %py_requires -d, um ebenso python-devel anzufordern.
- %python_sitelib - site-packages Verzeichnis für Plattform-unabhängige Module. Erweitert auf /usr/lib/python%{py_ver}/site-packages
- %python_sitearch - site-packages Verzeichnis für Plattform-abhängige Module. Erweitert auf %{_libdir}/python%{py_ver}/site-packages
Kompatibilität mit anderen Distributionen
Mit 11.1 wurde das getrennte Python-Paket eingeführt. Wenn Sie ein Paket für eine ältere Distribution bauen wollen, können Sie nicht python-base anfordern. Beachten Sie, dass python-base eingeführt wurde, weil es fast keine Bauzeit- oder Laufzeit-Abhängigkeiten hatte. Das bedeutet, dass es früher ungeblockt war während des Umbauzyklus. Wenn Ihr Paket keine Bauforderung python erfordert, kann es eher gebaut werden.
Die Möglichkeit, Architektur-unabhängige (noarch) mit %python_sitelib und %python_sitearch zu bauen, wurde mit 11.2 eingeführt. Wenn Sie eine Kompatibilität mit anderen Distributionen benötigen, müssen Sie die Makros definieren, die die Sie verwenden. Setzen Sie folgendes an den Anfang Ihrer Spezifikation:
%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())")} %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")}
Wenn Ihr Paket noarch ist, müssen Sie die noarch-Erklärung in eine bedingte Sequenz einpacken. Folgendes würde Ihr Paket als noarch nur ab openSUSE 11.2 bauen:
%if 0%{?suse_version} >= 1120 BuildArchitectures: noarch %endif
Und folgendes würde Ihr Paket als noarch ab openSUSE 11.2 bauen und jeder nicht-SUSE-Distribution bauen. (Geeignet, wenn Sie Pakete für Fedora bauen):
%if %{?suse_version: %{suse_version} > 1110} %{!?suse_version:1} BuildArchitectures: noarch %endif
Hinweise wie man Python3 Module packt
Dieser Text ist fortlaufender Bearbeitung. Mehr Details finden in dem Thread auf der openSUSE Paketbau Mailingliste. Verwendung auf eigenes Risiko. Die Hinweise die in diesem Abschnitt aufgelistet werden, sind Themen, die sich in der Zukunft ändern werden.
Die gleichen Prinzipien sind für Python3-Module anzuwenden. Es gibt einige Änderungen:
Bau von Python2 und Python3 Modulen gemeinsam
- Python 2.7 ist noch Standard
- Python Laufzeitpakete unterstützen Python(abi) Symbole ( zur Zeit in Versions 2.7 und 3.2), Module fordern die gegenseitigen Symbole (via rpm auto-dependency-generator)
- Um ein Paket zu bauen, das PythonX Module enthält, müssen Sie pythonX-devel zu BuildRequires hinzu fügen (python2-devel/python3-devel oder beide, wenn das Paket Module für beide Versionen unterstützt)
Wenn Ihr Python-Quellcode mit beiden Versionen kompatibel ist, verwende das folgende Verfahren:
- Starte mit python-foo.
- Erzeuge python-foo.spec.
- Baue es und behebe alle Fehler.
- Erzeuge ein neues Projekt mit osc linkpac:
osc home:YOUR_REPO python-foo home:YOUR_REPO python3-foo - Erzeuge eine python3-foo.spec im neuen Projekt.
- Wende alle Patche an, die für python3 vorhanden sind.
Schauen Sie im en:openSUSE:Python 3 Status nach einer Liste von Python Paketen und deren Python3 Status unter openSUSE.