Softwareinstallation für das Debian System
-
Inhalt
-
Einleitung
-
Das Debian-System
-
Paketmanager
-
Auf geht's
-
Voraussetzungen
-
Das Programm
-
Die Umgebung
-
Zum ersten Debian-Paket
-
Grundstruktur
-
Erste Anpassungen
-
Bauen
-
Das Menü
-
Ein Test
-
Feinschliff
-
lintian & linda
-
pbuilder
-
Tipps, Tricks & Sonstiges
-
Schlusswort
1 Einleitung
1.1 Das Debian System
Linuxdistributionen gibt es viele und die Paketsysteme sind nahezu ebenso vielfältig. Allerdings haben sich bei den großen Distributionen in Sachen Paketmanager zwei große Fraktionen gebildet. Einige, unter ihnen die großen kommerziellen Distributionen Red Hat (+ Fedora) und SuSE Linux verwenden den «Red Hat Package Manager» kurz rpm und Debian mit seinen «Kindern», dessen bekanntester, aber bei weitem nicht einziger Vertreter Ubuntu ist, verwenden libapt mit den .deb-Paketen. Und Debian an sich ist mehr als nur Linux! Es existieren auch Gnu/Hurd- und BSD-Releases.
Interessierte können einen bestimmt nicht vollständigen Stammbaum von Debian unter http://www.debian.org/misc/children-distros.de.html nachschlagen.
Und um die Pakete für genau diese Debian-Familie geht es in diesem Artikel.
1.2 Paketmanager
Doch was machen diese Paketmanager? Zu den Aufgaben der Paketmanager gehört neben der Installation von Software auch die Deinstallation, das Auflösen von Abhängigkeiten, die dafür sorgt, dass die Software nicht alle benötigten Bibliotheken mitbringen muss und sich trotzdem darauf verlassen kann, dass die benötigten Bibliotheken vorhanden sind.
2 Auf geht's
2.1 Voraussetzungen
Für den ersten Teil des Artikels wird neben dem Buildsystem, ich werde nur g++ verwenden, und der -dev-Version von libgtkmm die Debian-Tools benötigt.
- debhelper - Tools zum Erstellen von Paketen.
- dh-make - Tool um Pakete zu initiieren
- lintian - Tool, das die fertigen Pakete überprüft.
- fakeroot - damit man nicht jedes Mal zum Bauen Superuser-Rechte benötigt
2.2 Das Programm
Als zu Software verwende ich das Beispielprogramm, das schon im Artikel zur «Softwareinstallation unter Linux» von joomoo verwendet wurde:
#include <gtkmm.h> int main(int argc, char** argv) { Gtk::Main kit(argc, argv); Gtk::Window win; Gtk::Image img("/usr/share/hallowelt/hallowelt.png"); win.add(img); win.show_all(); kit.run(win); }
2.3 Die Umgebung
Die Debian-Tools erwarten, dass sich die Software, die wir packen wollen in einem Verzeichnis nach dem Muster <paketname>-<version> befindet. Auch wenn man dies umgehen kann, halten wir uns erst einmal an diese Vorgaben und erstellen das Verzeichnis
hallowelt-1.0.0/
und legen das obige C++-Programm dort ab.Auch das Bild legen wir hier ab. Wer will, kann sich überzeugen, dass er das Programm jetzt mit g++ kompilieren kann. Allerdings sollte am Ende das Verzeichnis nur
- main.cpp
- hallowelt.png
- hallowelticon.png
enthalten, im Allgemeinen ein sauberes Sourcearchiv ohne Überreste von Builds oder ähnlichem.
3 Zum ersten Debian-Paket
3.1 Die Grundstruktur
Die Grundstruktur eines Debian-Paketes wird mit dem Tool dh_make erstellt:
$ ls -lh insgesamt 12K -rw-r--r-- 1 christoph christoph 2,4K 2008-02-15 21:07 hallowelt.png -rw-r--r-- 1 christoph christoph 175 2008-02-15 21:06 hallowelticon.png -rw-r--r-- 1 christoph christoph 210 2008-02-15 20:56 main.cpp $ dh_make --createorig -e christoph@coders-nemesis.eu Type of package: single binary, multiple binary, library, kernel module or cdbs? [s/m/l/k/b] s Maintainer name : Christoph Egger Email-Address : christoph@coders-nemesis.eu Date : Fri, 15 Feb 2008 21:08:59 +0100 Package Name : hallowelt Version : 1.0.0 License : blank Type of Package : Single Hit <enter> to confirm: Currently there is no top level Makefile. This may require additional tuning. Done. Please edit the files in the debian/ subdirectory now. You should also check that the hallowelt Makefiles install into $DESTDIR and not in / .
Mit dem Schalter --createorig (-r) teilen wir mit, dass noch kein Tarball mit allen Dateien besteht (dieser wird normalerweise verwendet um die Modifikationen des Paketbaus von der Software selbst zu trennen). dh_make erstellt dann einen solchen im Verzeichnis, in dem sich auch das Verzeichnis hallowelt-1.0.0 befindet.
Mit der Option -e E-Mail-Adresse geben wir unsere E-Mail-Adresse an, da dh_make sonst username@_computername_ annimmt, was in unserem Fall wenig Sinn macht.
$ ls .. -lh insgesamt 12K drwxr-xr-x 3 christoph christoph 4,0K 2008-02-15 21:09 hallowelt-1.0.0 drwxr-xr-x 2 christoph christoph 4,0K 2008-02-15 21:07 hallowelt-1.0.0.orig
Danach fragt dh_make welcher Art die Software ist, die wir packen wollen. Ich habe hier single binary gewählt. Dann gibt es einen Überblick über die Paketdaten - wir können diese später jederzeit ändern.
Zum Schluss werden wir noch darauf hingewiesen, dass dh_make kein Makefile gefunden hat und wir uns selbst um die Erstellung der Software kümmern müssen.
Wenn alles glatt gelaufen ist, sollte sich jetzt in unserem Projektverzeichnis (
hallowelt-1.0.0
) ein Unterverzeichnisdebian
befinden, das in etwa so aussieht:$ ls -lh debian insgesamt 116K -rw-r--r-- 1 christoph christoph 193 2008-02-15 21:09 changelog -rw-r--r-- 1 christoph christoph 2 2008-02-15 21:09 compat -rw-r--r-- 1 christoph christoph 337 2008-02-15 21:09 control -rw-r--r-- 1 christoph christoph 672 2008-02-15 21:09 copyright -rw-r--r-- 1 christoph christoph 87 2008-02-15 21:09 cron.d.ex -rw-r--r-- 1 christoph christoph 17 2008-02-15 21:09 dirs -rw-r--r-- 1 christoph christoph 0 2008-02-15 21:09 docs -rw-r--r-- 1 christoph christoph 1,3K 2008-02-15 21:09 emacsen-install.ex -rw-r--r-- 1 christoph christoph 477 2008-02-15 21:09 emacsen-remove.ex -rw-r--r-- 1 christoph christoph 1,2K 2008-02-15 21:09 emacsen-startup.ex -rw-r--r-- 1 christoph christoph 241 2008-02-15 21:09 hallowelt-default.ex -rw-r--r-- 1 christoph christoph 541 2008-02-15 21:09 hallowelt.doc-base.EX -rw-r--r-- 1 christoph christoph 4,1K 2008-02-15 21:09 init.d.ex -rw-r--r-- 1 christoph christoph 8,4K 2008-02-15 21:09 init.d.lsb.ex -rw-r--r-- 1 christoph christoph 1,8K 2008-02-15 21:09 manpage.1.ex -rw-r--r-- 1 christoph christoph 4,6K 2008-02-15 21:09 manpage.sgml.ex -rw-r--r-- 1 christoph christoph 4,5K 2008-02-15 21:09 manpage.xml.ex -rw-r--r-- 1 christoph christoph 132 2008-02-15 21:09 menu.ex -rw-r--r-- 1 christoph christoph 961 2008-02-15 21:09 postinst.ex -rw-r--r-- 1 christoph christoph 934 2008-02-15 21:09 postrm.ex -rw-r--r-- 1 christoph christoph 694 2008-02-15 21:09 preinst.ex -rw-r--r-- 1 christoph christoph 881 2008-02-15 21:09 prerm.ex -rw-r--r-- 1 christoph christoph 186 2008-02-15 21:09 README.Debian -rwxr-xr-x 1 christoph christoph 1,8K 2008-02-15 21:09 rules -rw-r--r-- 1 christoph christoph 684 2008-02-15 21:09 watch.ex
3.2 Erste Anpassungen
Im
debian
Verzeichnis sind jetzt jede Menge Dateien von denen wir eine ganze Menge nicht benötigen.cron.d
dient zum Eintragen von Cronjobs unseres Programms,init.d.ex
falls unser Programm beim Systemstart mitgeladen werden soll,manpage.*.ex
für manpage Einträgepre/post inst/rm
für Skripte, die vor/nach dem Installieren/Deinstallieren ausgeführt werden sollenemacsen*
falls sich unser Programm in Emacs integrieren soll
Da wir sie für dieses Programm nicht benötigen, können wir sie gleich löschen. Sehen wir uns an, was übriggeblieben ist.
3.2.1 debian/control
Die debian/control sollte in etwa so aussehen:
Source: hallowelt Section: unknown Priority: extra Maintainer: Christoph Egger <christoph@coders-nemesis.eu> Build-Depends: debhelper (>= 5) Standards-Version: 3.7.2 Package: hallowelt Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: <insert up to 60 chars description> <insert long description, indented with spaces>
<insert up to 60 chars description>
ersetzen wir mit einer Kurzbeschreibung für das Programm, beispielsweiseGrußprogramm
,<insert long description, indented with spaces>
gibt uns Platz, etwas ausführlicher zu werden:hallowelt ist ein kleines Programm, das die Welt auf Deutsch grüßt. . hallowelt verwendet GTKmm als GUI-Toolkit
Dieser Text muss in jeder neuen Zeile mit einem Leerzeichen beginnen. Einen neuen Absatz erhält man mit einer Zeile, die nur ein Leerzeichen und einen Punkt enthält.
3.2.2 debian/copyright
This package was debianized by Christoph Egger <christoph@coders-nemesis.eu> on Fri, 15 Feb 2008 21:08:59 +0100. It was downloaded from <url://example.com> Upstream Author(s): <put author's name and email here> <likewise for another author> Copyright: <Copyright (C) YYYY Name OfAuthor> <likewise for another author> License: <Put the license of the package here indented by 4 spaces> The Debian packaging is (C) 2008, Christoph Egger <christoph@coders-nemesis.eu> and is licensed under the GPL, see `/usr/share/common-licenses/GPL'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here.
Wieder müssen wir anpassen, was in den spitzen Klammern steht (Ausnahme ist die E-Mail-Adresse)
This package was debianized by Christoph Egger <christoph@coders-nemesis.eu> on Fri, 15 Feb 2008 21:08:59 +0100. It was downloaded from http://magazin.c-plusplus.net/ Upstream Author(s): joomoo <jhasse@gmail.com> Copyright: Copyright (C) 2008 joomoo License: Veröffentlicht unter der GNU GPL v3, siehe auch /usr/share/common-licenses/GPL-3 The Debian packaging is (C) 2008, Christoph Egger <christoph@coders-nemesis.eu> and is licensed under the GPL, see `/usr/share/common-licenses/GPL'. # Please also look if there are files or directories which have a # different copyright/license attached and list them here.
3.2.3 debian/rules
Das Herzstück der Paketierung. Es handelt sich hierbei um ein GNU-Makefile, das die Regeln für die einzelnen Schritte enthält.
build-stamp: configure-stamp dh_testdir # Add here commands to compile the package. $(MAKE) #docbook-to-man debian/hallowelt.sgml > hallowelt.1 touch $@
In diesem Ausschnitt müssen wir angeben, wie die Software gebaut wird.
Ersetzen wir
$(MAKE)
mitg++ main.cpp -o hallowelt
pkg-config gtkmm-2.4 --cflags --libs``install: build dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/hallowelt. $(MAKE) DESTDIR=$(CURDIR)/debian/hallowelt install
Hier ersetzen wir
$(MAKE) DESTDIR=$(CURDIR)/debian/hallowelt install
mitmv hallowelt debian/hallowelt/usr/bin/ cp hallowelt.png debian/hallowelt/usr/share/hallowelt/ cp hallowelticon.png debian/hallowelt/usr/share/icons/hallowelticon.png
clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. $(MAKE) clean dh_clean
$(MAKE) clean
können wir entfernen, da die ausführbare Datei bereits in das debian/hallowelt Verzeichnis verschoben wird, das von dh_clean aufgeräumt wird, und sonst keine Reste bleiben.3.3 Bauen
Mit
dpkg-buildpackage
wird das Paket dann gebaut:$ dpkg-buildpackage dpkg-buildpackage: Quellpaket hallowelt dpkg-buildpackage: Quellversion 1.0.0-1 dpkg-buildpackage: Quellen geändert durch Christoph Egger <christoph@coders-nemesis.eu> dpkg-buildpackage: Host-Architektur i386 fakeroot debian/rules clean dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. # /usr/bin/make clean dh_clean dpkg-source -b hallowelt-1.0.0 dpkg-source: baue hallowelt in hallowelt_1.0.0.orig.tar.gz dpkg-source: baue hallowelt in hallowelt_1.0.0-1.diff.gz dpkg-source: Warnung: newly created empty file 'debian/docs' will not be represented in diff dpkg-source: baue hallowelt in hallowelt_1.0.0-1.dsc debian/rules build dh_testdir # Add here commands to configure the package. touch configure-stamp dh_testdir # Add here commands to compile the package. g++ main.cpp -o hallowelt `pkg-config gtkmm-2.4 --cflags --libs` #docbook-to-man debian/hallowelt.sgml > hallowelt.1 touch build-stamp fakeroot debian/rules binary dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/hallowelt. mv hallowelt debian/hallowelt/usr/bin/ cp *.png debian/hallowelt/usr/share/hallowelt/ cp: angegebenes Ziel "debian/hallowelt/usr/share/hallowelt/" ist kein Verzeichnis: Datei oder Verzeichnis nicht gefunden make: *** [install] Fehler 1 dpkg-buildpackage: Fehlschlag: fakeroot debian/rules binary gab Fehler-Exitstatus 2
Wir versuchen also, eine Datei in ein nicht existentes Verzeichnis zu kopieren. Um den Fehler zu vermeiden, teilen wir dpkg mit, welche Verzeichnisse benötigt werden. Dies geschieht in der Datei
debian/dirs
. Dort fügen wir jetzt folgende Einträge hinzu:usr/share usr/share/hallowelt usr/share/icons
Die Verzeichnisse müssen rekursiv hinzugefügt werden, da das Erstellen von usr/share/hallowelt fehlschlagen muss, wenn usr/share nicht existiert.
Jetzt läuft
dpkg-buildpackage
erfolgreich durch:$ dpkg-buildpackage dpkg-buildpackage: Quellpaket hallowelt dpkg-buildpackage: Quellversion 1.0.0-1 dpkg-buildpackage: Quellen geändert durch Christoph Egger <christoph@coders-nemesis.eu> dpkg-buildpackage: Host-Architektur i386 fakeroot debian/rules clean dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. # /usr/bin/make clean dh_clean dpkg-source -b hallowelt-1.0.0 dpkg-source: building hallowelt using existing hallowelt_1.0.0.orig.tar.gz dpkg-source: baue hallowelt in hallowelt_1.0.0-1.diff.gz dpkg-source: Warnung: file debian/dirs has no final newline (either original or modified version) dpkg-source: Warnung: newly created empty file 'debian/docs' will not be represented in diff dpkg-source: baue hallowelt in hallowelt_1.0.0-1.dsc debian/rules build dh_testdir # Add here commands to configure the package. touch configure-stamp dh_testdir # Add here commands to compile the package. g++ main.cpp -o hallowelt `pkg-config gtkmm-2.4 --cflags --libs` #docbook-to-man debian/hallowelt.sgml > hallowelt.1 touch build-stamp fakeroot debian/rules binary dh_testdir dh_testroot dh_clean -k dh_installdirs # Add here commands to install the package into debian/hallowelt. mv hallowelt debian/hallowelt/usr/bin/ cp *.png debian/hallowelt/usr/share/hallowelt/ dh_testdir dh_testroot dh_installchangelogs dh_installdocs dh_installexamples dh_installman dh_link dh_strip dh_compress dh_fixperms dh_installdeb dh_shlibdeps dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libgdkmm-2.4.so.1 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libatkmm-1.6.so.1 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libgtk-x11-2.0.so.0 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libpangomm-1.4.so.1 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libcairomm-1.0.so.1 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libsigc-2.0.so.0 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libgdk-x11-2.0.so.0 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libatk-1.0.so.0 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libgdk_pixbuf-2.0.so.0 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libpangocairo-1.0.so.0 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libpango-1.0.so.0 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libcairo.so.2 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libgobject-2.0.so.0 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libgmodule-2.0.so.0 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libdl.so.2 gelinkt werden (es verwendet keine seiner Symbole). dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libglib-2.0.so.0 gelinkt werden (es verwendet keine seiner Symbole). dh_gencontrol dpkg-gencontrol: Warnung: unbekannte Substitutionsvariable ${misc:Depends} dh_md5sums dh_builddeb dpkg-deb: Baue Paket »hallowelt« in »../hallowelt_1.0.0-1_i386.deb«. signfile hallowelt_1.0.0-1.dsc gpg: »Christoph Egger <christoph@coders-nemesis.eu>« übersprungen: Geheimer Schlüssel ist nicht vorhanden gpg: [stdin]: clearsign failed: Geheimer Schlüssel ist nicht vorhanden dpkg-genchanges >../hallowelt_1.0.0-1_i386.changes dpkg-genchanges: füge kompletten Quellcode beim Hochladen hinzu dpkg-buildpackage: Alles hochzuladen (Originalquellen enthalten) dpkg-buildpackage: Warnung: Konnte .dsc- und .changes-Datei nicht signieren
Gehen wir die Warnungen der Reihe nach durch:
dpkg-source: Warnung: file debian/dirs has no final newline (either original or modified version)
Das ist relativ eindeutig. Ich habe vergessen, die Textdatei debian/dirs mit einem Newline-Zeichen abzuschließen. Das ist ziemlich schnell repariert also weiter zur nächsten Warnung:
dpkg-source: Warnung: newly created empty file 'debian/docs' will not be represented in diff
Die Datei debian/docs enthält eine mit Newline separierte Liste an Dateien, die die Dokumentation des Programms bilden und später unter /usr/share/doc/hallowelt/ abgelegt werden.
Diese Warnung können wir ignorieren oder eine Dokumentation erstellen und in die Datei eintragen. Kommen wir zu den nächsten Warnungen:dpkg-shlibdeps: Warnung: debian/hallowelt/usr/bin/hallowelt sollte nicht gegen libgdkmm-2.4.so.1 gelinkt werden (es verwendet keine seiner Symbole).
Durch die Verwendung von `pkg-config gtkmm-2.4 --libs` haben wir einige libs mitgelinkt, die von unserem kleinen Programm gar nicht verwendet werden. Wir können uns jetzt entscheiden, die benötigten libs einzeln aufzulisten oder die Warnung ebenfalls ignorieren. Da die gtkmm von diesen Bibliotheken abhängt, bekommen wir durch ihre Verwendung keine zusätzlichen Abhängigkeiten und die libs werden auch nur dynamisch geladen, sodass dies keinen allzu großen Einfluss auf die Größe des Programms hat. Bleibt noch eine Warnung:
gpg: skipped "Christoph Egger <christoph@coders-nemesis.eu>": secret key not available
Der GPG-Fehler weist darauf hin, dass wir für die verwendete E-Mail-Adresse keinen privaten GPG-Schlüssel besitzen. GPG wird bei den Debian-Paketen dazu verwendet, den Ersteller zu identifizieren und dient nebenbei als Checksumme. Der Schlüssel wird mit
gpg --gen-key
erstellt. Für Näheres sei hier aufman gpg(1)
verwiesen.$dpkg-buildpackage [...] dh_md5sums dh_builddeb dpkg-deb: Baue Paket »hallowelt« in »../hallowelt_1.0.0-1_i386.deb«. signfile hallowelt_1.0.0-1.dsc You need a passphrase to unlock the secret key for user: "Christoph Egger <christoph@coders-nemesis.eu>" 1024-bit DSA key, ID 8DCFF142, created 2007-12-29 dpkg-genchanges >../hallowelt_1.0.0-1_i386.changes dpkg-genchanges: füge kompletten Quellcode beim Hochladen hinzu signfile hallowelt_1.0.0-1_i386.changes You need a passphrase to unlock the secret key for user: "Christoph Egger <christoph@coders-nemesis.eu>" 1024-bit DSA key, ID 8DCFF142, created 2007-12-29 dpkg-buildpackage: Alles hochzuladen (Originalquellen enthalten)
3.4 Das Menü
Was uns jetzt noch fehlt ist der Menüeintrag. In der debian/rules fällt hierzu der Eintrag dh_installmenu auf. Die man-Page zu diesem Befehl verrät, was wir machen müssen: Wir legen die Datei
debian/hallowelt.menu
an:?package(hallowelt):needs="X11" section="Applications/Graphics"\ title="hallowelt" command="/usr/bin/hallowelt"\ icon="/usr/share/icons/helloworldicon.png"
und entfernen das '#' vor dem dh_installmenu, sodass der Befehl ausgeführt wird.
Wobei Applications/Graphics nur eine «Notlösung» ist, da ich keine bessere Kategorie gefunden habe. Eine Auflistung aller Kategorien findet man unter
man 5 menufile
, dort befinden sich auch weitere Informationen und optionale Argumente für den Aufbau des Menüs.3.5 Ein Test
Jetzt ist es an der Zeit, einmal auszuprobieren, was wir bisher erreicht haben. Das Paket befindet sich in .. und kann z.B. mit
sudo dpkg -i ../hallowelt_1.0.0-1_i386.deb
installiert werden (i386 ist die Architektur, bei mir steht hier i386 weil ich einen Intel-kompatiblen Prozessor und ein 32bit-Linux verwende).Wenn man jetzt sein Menü öffnet, sollte sich in der Sektion Grafik ein Eintrag Hallowelt mit dem Icon befinden. Das Programm lässt sich auch ausführen. ~"du" durch "man" ersetzt~
Wenn man
dpkg -r
wieder entfernt, sollte der Menüeintrag wieder verschwunden sein und ein Starten aus einem Terminal heraus ebenfalls fehlschlagen:$ hallowelt bash: hallowelt: command not found
4 Der Feinschliff
4.1 lintian
Bei lintian handelt es sich um ein Programm, das die Struktur von Debian-Paketen auf Fehler überprüft. Sehen wir uns also einmal an, was sie zu unserem Hallowelt-Programm zu sagen haben:
$ cd .. $ lintian `ls . | grep deb` W: hallowelt: binary-without-manpage usr/bin/hallowelt W: hallowelt: package-contains-empty-directory usr/sbin/ W: hallowelt: readme-debian-contains-debmake-template W: hallowelt: copyright-lists-upstream-authors-with-dh_make-boilerplate W: hallowelt: copyright-contains-dh_make-todo-boilerplate E: hallowelt: menu-icon-not-in-xpm-format /usr/share/icons/helloworldicon.png W: hallowelt: spelling-error-in-description programm program E: hallowelt: section-is-dh_make-template W: hallowelt: new-package-should-close-itp-bug W: hallowelt: wrong-bug-number-in-closes l3:#nnnn
Von oben nach unten:
- Die Debian-Policy fordert, dass für jedes Programm eine Man-Page existiert. Da aber hallowelt keinerlei Optionen anbietet und keinerlei Nutzen hat, können wir das wohl getrost ignorieren.
- Die Datei
debian/dirs
enthält noch eine Zeileusr/sbin
(sbin steht für System Binary), aber wir legen nichts in diesem Verzeichnis ab. Diese Warnung können wir also mit dem Entfernen der entsprechenden Zeile aus derdebian/dirs
beheben. - Die
debian/README.Debian
enthält noch «Template-Text». Sehen wir uns die Datei an:
hallowelt for Debian -------------------- <possible notes regarding this package - if none, delete this file> -- Christoph Egger <christoph@coders-nemesis.eu> Fri, 15 Feb 2008 21:08:59 +0100
Schreiben wir also etwas Sinnvolles hinein und ersetzen den Text in den spitzigen Klammern (einschließlich der Klammern).
Das gleiche können wir für die anderen «Template-Fehler» machen.
- copyright-lists-upstream-authors-with-dh_make-boilerplate - Wenn wir in unsere
debian/copyright
sehen, stellen wir fest, dass dort Upstream Author(s) steht. Da wir nur einen Upstream Author haben entfernen wir das(s)
einfach (sollten es mehrere Upstream Authors sein müssen die Klammern entfernt werden) - Ebenfalls in der
debian/copyright
befindet sich noch folgende Anmerkung:
# Please also look if there are files or directories which have a # different copyright/license attached and list them here.
Auch diese können wir (nachdem wir den Hinweis beachtet haben) herauslöschen.
- Das Icon ist nicht im xpm-Format. Auch hierbei handelt es sich um einen Bestandteil der Debian-Policy, das Paket funktioniert aber auch, wie wir gesehen haben, mit dem png-Icon.
- Hier sehen wir etwas Interessantes: lintian prüft die Rechtschreibung (allerdings nur die englische, Paketbeschreibungen sollten an sich immer Englisch sein)
- Die Section «unknown» (jetzt geht es nicht um Menü-Sektionen, sondern um die Anwendung selbst) existiert nicht. Wir entscheiden uns für die Sektion «devel», da das Paket ja als «Hilfe» zum Entwickeln gedacht ist (dies orientiert sich auch an dem Beispielpaket hello, das bereits im Repository ist und denselben Zweck hat wie unser Paket).
- Wenn für die Debian-Distribution gepackt wird, erstellt der Packager einen «Fehlerbericht», in dem er seine Absichten ankündigt. Dies geschieht als Fehler des «Pakets» wnpp, das ausschließlich für diesen Zweck existiert. Dieser Fehlerbericht wird natürlich hinfällig, wenn das Paket fertig ist, daher sollte das Paket den Fehlerbericht schließen. Da wir keinen WNPP-Fehlerbericht erstellt haben, müssen wir den Fehler wohl ignorieren. In der
debian/changelog
entfernen wir außerdem den Rest der Zeile, die mit « * initial Release» beginnt.
Sehen wir uns an, was wir erreicht haben:
$ ( cd hallo* ; dpkg-buildpackage -uc -us) ; lintian `ls . | grep deb` [..] W: hallowelt: binary-without-manpage usr/bin/hallowelt E: hallowelt: menu-icon-not-in-xpm-format /usr/share/icons/helloworldicon.png W: hallowelt: new-package-should-close-itp-bug
Sieht schon deutlich besser aus.
4.2 pbuilder
Bis jetzt haben wir das Paket mit dpkg-buildpackage gebaut. Man kann dies als den «schnellen Weg» bezeichnen, allerdings empfiehlt es sich, sollte man das Paket später veröffentlichen wollen, dem Umweg über pbuilder zu nehmen. pbuilder stellt sicher, dass alle Abhängigkeiten des Pakets erfüllt sind und nicht gegen neuere Bibliotheken gelinkt wird, die man sich auf seinem Arbeitssystem installiert hat, die aber für die Zieldistribution noch nicht vorhanden sind.
Außerdem ist es mit pbuilder möglich, das Paket für verschiedene Distributionen zu bauen, auch für verschiedene Debian-Erben, ohne sich jedes dieser Systeme installieren zu müssen.
4.2.1 Setup
Als erstes muss, nachdem pbuilder installiert wurde, eine Umgebung errichtet werden. Dies geschiet mit dem Kommando
sudo pbuilder --create [--distribution NAME]
Wird keine Distribution angegeben, so wird ein pbuilder für die aktuell verwendete Distribution errichtet. pbuilder initialisiert hier eine base.tgz, die alle wichtigen Dateien enthält. Wenn man mit
--basetgz
ein Ort angegeben hat, kann man auch pbuilder-Umgebungen für verschiedene Distributionen errichten.4.3.2 Der erste Durchlauf
Zum Bauen mit pbuilder wird ein sogenanntes Source-Paket benötigt. dpkg-buildpackage baut ein solches gleich mit (man kann das durch die Option -b abschalten), sodass wir gleich anfangen können. Später können wir uns das Kompilieren beim dpkg-buildpackage sparen, indem wir die Option -S verwenden, kompiliert wird das Ganze ja im pbuilder.
Der Aufruf erfolgt über
sudo pbuilder --build *.dsc
Und schon wieder gibt es einige Fehler zu beheben:
$ sudo pbuilder --build `ls . | grep dsc` [sudo] password for christoph: W: /home/christoph/.pbuilderrc does not exist I: using fakeroot in build. Current time: Mon Mar 17 14:40:54 CET 2008 pbuilder-time-stamp: 1205761254 Building the build Environment -> extracting base tarball [[b][/b]/var/cache/pbuilder/base.tgz] -> creating local configuration -> copying local configuration -> mounting /proc filesystem -> mounting /dev/pts filesystem -> policy-rc.d already exists Obtaining the cached apt archive contents Installing the build-deps dpkg-architecture: warning: no utmp entry available and LOGNAME not defined; using uid of process (0) -> Attempting to satisfy build-dependencies -> Creating pbuilder-satisfydepends-dummy package Package: pbuilder-satisfydepends-dummy Version: 0.invalid.0 Architecture: i386 Maintainer: Debian Pbuilder Team <pbuilder-maint@lists.alioth.debian.org> Description: Dummy package to satisfy dependencies with aptitude - created by pbuilder This package was created automatically by pbuilder and should Depends: debhelper (>= 5) dpkg-deb: building package `pbuilder-satisfydepends-dummy' in `/tmp/satisfydepends-aptitude/pbuilder-satisfydepends-dummy.deb'. Reading package lists... Done Building dependency tree... Done aptitude is already the newest version. 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Selecting previously deselected package pbuilder-satisfydepends-dummy. (Reading database ... 9699 files and directories currently installed.) Unpacking pbuilder-satisfydepends-dummy (from .../pbuilder-satisfydepends-dummy.deb) ... dpkg: dependency problems prevent configuration of pbuilder-satisfydepends-dummy: pbuilder-satisfydepends-dummy depends on debhelper (>= 5); however: Package debhelper is not installed. dpkg: error processing pbuilder-satisfydepends-dummy (--install): dependency problems - leaving unconfigured Errors were encountered while processing: pbuilder-satisfydepends-dummy Reading package lists... Done Building dependency tree... Done Initializing package states... Done Building tag database... Done The following NEW packages will be automatically installed: debhelper file gettext gettext-base html2text intltool-debian libmagic1 po-debconf The following NEW packages will be installed: debhelper file gettext gettext-base html2text intltool-debian libmagic1 po-debconf The following packages are RECOMMENDED but will NOT be installed: curl libcompress-zlib-perl libmail-sendmail-perl lynx lynx-cur wget 0 packages upgraded, 8 newly installed, 0 to remove and 0 not upgraded. Need to get 0B/3370kB of archives. After unpacking 11.3MB will be used. Writing extended state information... Done Selecting previously deselected package libmagic1. (Reading database ... 9699 files and directories currently installed.) Unpacking libmagic1 (from .../libmagic1_4.17-5etch2_i386.deb) ... Selecting previously deselected package file. Unpacking file (from .../file_4.17-5etch2_i386.deb) ... Selecting previously deselected package html2text. Unpacking html2text (from .../html2text_1.3.2a-3_i386.deb) ... Selecting previously deselected package gettext-base. Unpacking gettext-base (from .../gettext-base_0.16.1-1_i386.deb) ... Selecting previously deselected package gettext. Unpacking gettext (from .../gettext_0.16.1-1_i386.deb) ... Selecting previously deselected package intltool-debian. Unpacking intltool-debian (from .../intltool-debian_0.35.0+20060710.1_all.deb) ... Selecting previously deselected package po-debconf. Unpacking po-debconf (from .../po-debconf_1.0.8_all.deb) ... Selecting previously deselected package debhelper. Unpacking debhelper (from .../debhelper_5.0.42_all.deb) ... Setting up libmagic1 (4.17-5etch2) ... Setting up file (4.17-5etch2) ... Setting up html2text (1.3.2a-3) ... Setting up gettext-base (0.16.1-1) ... Setting up gettext (0.16.1-1) ... Setting up intltool-debian (0.35.0+20060710.1) ... Setting up po-debconf (1.0.8) ... Setting up debhelper (5.0.42) ... Setting up pbuilder-satisfydepends-dummy (0.invalid.0) ... -> Finished parsing the build-deps Reading package lists... Done Building dependency tree... Done fakeroot is already the newest version. 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Copying back the cached apt archive contents Copying source file -> copying [hallowelt_1.0.0-1.dsc] -> copying [./hallowelt_1.0.0.orig.tar.gz] -> copying [./hallowelt_1.0.0-1.diff.gz] Extracting source dpkg-source: extracting hallowelt in hallowelt-1.0.0 dpkg-source: unpacking hallowelt_1.0.0.orig.tar.gz dpkg-source: applying ./hallowelt_1.0.0-1.diff.gz -> Building the package dpkg-buildpackage: source package is hallowelt dpkg-buildpackage: source version is 1.0.0-1 dpkg-buildpackage: source changed by Christoph Egger <christoph@coders-nemesis.eu> dpkg-buildpackage: host architecture i386 dpkg-buildpackage: source version without epoch 1.0.0-1 fakeroot debian/rules clean dh_testdir dh_testroot rm -f build-stamp configure-stamp # Add here commands to clean up after the build process. # /usr/bin/make clean dh_clean dpkg-source -b hallowelt-1.0.0 dpkg-source: building hallowelt using existing hallowelt_1.0.0.orig.tar.gz dpkg-source: building hallowelt in hallowelt_1.0.0-1.diff.gz dpkg-source: building hallowelt in hallowelt_1.0.0-1.dsc debian/rules build dh_testdir # Add here commands to configure the package. touch configure-stamp dh_testdir # Add here commands to compile the package. g++ main.cpp -o hallowelt `pkg-config gtkmm-2.4 --cflags --libs` /bin/sh: pkg-config: command not found main.cpp:1:20: error: gtkmm.h: No such file or directory main.cpp: In function 'int main(int, char**)': main.cpp:5: error: 'Gtk' has not been declared main.cpp:5: error: expected `;' before 'kit' main.cpp:6: error: 'Gtk' has not been declared main.cpp:6: error: expected `;' before 'win' main.cpp:7: error: 'Gtk' has not been declared main.cpp:7: error: expected `;' before 'img' main.cpp:8: error: 'win' was not declared in this scope main.cpp:8: error: 'img' was not declared in this scope main.cpp:10: error: 'kit' was not declared in this scope make: *** [build-stamp] Error 1 pbuilder: Failed autobuilding of package -> Aborting with an error -> unmounting dev/pts filesystem -> unmounting proc filesystem -> cleaning the build env -> removing directory /var/cache/pbuilder/build//7581 and its subdirectories
Zuerst «installiert» pbuilder einige Pakete in seiner Umgebung, dann versucht er, das Paket zu bauen. Allerdings kann pbuilder weder das Programm pkg-config noch die gtkmm-Header finden. Dies ist auch logisch, wenn man sich die
debian/control
ansieht. Fügen wir dort also bei denBuild-Depends
(mit einem Komma abgetrennt) das Paket «libgtkmm-2.4-dev» hinzu. Das ganze sieht dann in etwa so aus:Source: hallowelt Section: devel Priority: extra Maintainer: Christoph Egger <christoph@coders-nemesis.eu> Build-Depends: debhelper (>= 5), libgtkmm-2.4-dev Standards-Version: 3.7.2 Package: hallowelt Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Grußprogramm hallowelt ist ein kleines Programm, das die Welt auf Deutsch grüßt. . hallowelt verwendet GTKmm als GUI-Toolkit
Jetzt sollte der Build fehlerfrei durchlaufen (Neubau des Source-Pakets nicht vergessen bevor der pbuilder aufgerufen wird!) und das Ergebnis unserer Arbeit unter
/var/cache/pbuilder/result
zu finden sein:$ ls -lh /var/cache/pbuilder/result insgesamt 35M -rw-r--r-- 1 christoph christoph 2,5K 2008-03-17 14:55 hallowelt_1.0.0-1.diff.gz -rw-r--r-- 1 christoph christoph 356 2008-03-17 14:55 hallowelt_1.0.0-1.dsc -rw-r--r-- 1 christoph christoph 732 2008-03-17 14:56 hallowelt_1.0.0-1_i386.changes -rw-r--r-- 1 christoph christoph 7,4K 2008-03-17 14:56 hallowelt_1.0.0-1_i386.deb -rw-r--r-- 1 christoph christoph 2,9K 2008-02-15 21:56 hallowelt_1.0.0.orig.tar.gz
Nachdem dieses Paket installiert wurde, kann man mit
aptitude show hallowelt
noch einmal betrachten, was zu unserem Paket zu sagen ist:$ aptitude show hallowelt Kann kein Archiv »testing« für das Paket »hallowelt« finden Paket: hallowelt Neu: ja Zustand: Installiert Automatisch installiert: ja Version: 1.0.0-1 Priorität: extra Bereich: devel Verwalter: Christoph Egger <christoph@coders-nemesis.eu> Unkomprimierte Größe: 81,9k Hängt ab von: libatk1.0-0 (>= 1.12.2), libc6 (>= 2.3.6-6), libcairo2 (>= 1.2.4), libfontconfig1 (>= 2.4.0), libgcc1 (>= 1:4.1.1-12), libglib2.0-0 (>= 2.12.0), libglibmm-2.4-1c2a, libgtk2.0-0 (>= 2.8.0), libgtkmm-2.4-1c2a, libpango1.0-0 (>= 1.14.8), libsigc++-2.0-0c2a (>= 2.0.2), libstdc++6 (>= 4.1.1-12), libx11-6, libxcursor1 (> 1.1.2), libxext6, libxfixes3 (>= 1:4.0.1), libxi6, libxinerama1, libxrandr2, libxrender1 Beschreibung: Application greeting the world hallowelt ist ein kleines Program, das die Welt auf Deutsch grüßt. hallowelt uses the gtkmm library as it's graphics toolkit.
Da wir als build-Abhängigkeit libgtkmm-2.4-dev angegeben haben, hat pbuilder (und auch dpkg-buildpackage) bereits einiges an Abhängigkeiten hinzugefügt, ohne dass wir uns darum kümmern müssen. Hier zeigt sich, warum das Verwenden von pbuilder so hilfreich ist, um korrekte Pakete zu erstellen.
5 Tipps, Tricks & Sonstiges
An dieser Stelle möchte ich noch ein paar Tipps loswerden.
Manchmal ist es nicht so einfach, die richtigen Abhängigkeiten zu finden, um das Paket zu bauen. Insbesondere wenn diese Pakete alle bereits installiert waren und für das Entwickeln nicht installiert werden mussten oder wenn man Fremdsoftware packt. Hier hilft das tool apt-file, mit dem man die Paketquellen nach Dateinamen durchsuchen kann.
Beim Gegentesten des Artikels auf meinem alten PC mit Ubuntu 7.10 ist mir aufgefallen, dass sich das Verhalten bei einigen Details von dem meines Notebooks mit Debian lenny unterscheidet. So war z.B. unter Ubuntu die explizite Angabe von
-rfakeroot
nötig, während Debian fakeroot gleich mitinstalliert und verwendet hatte. Auch scheint der Menüeintrag im GNOME-Menü nicht zu erscheinen. Das fluxbox meines Notebooks hat hier keine Probleme gemacht.Alle wichtigen Informationen sind auf der Debian-Website im Entwicklerbereich vorhanden:
http://www.debian.org/devel/
Und zum Paketbau direkt:
http://www.debian.org/doc/manuals/maint-guide/index.de.html6 Schlusswort
Ich hoffe, ich konnte in diesem Artikel einen kleinen Einblick in den Paketbau für Debian-Systeme geben und dem einen oder anderen hier weiterhelfen.
Natürlich ist hier bei weitem noch nicht alles abgedeckt; das Verfahren, eine Bibliothek zu packen, unterscheidet sich deutlich, man-pages müssen normalerweise vorhanden sein und bei komplexeren Programmen müssen mehr und komplexere Abhängigkeiten betrachtet werden.
Ich wünsche viel Spaß beim Packen und vielleicht wird hier ja noch der eine oder andere irgendwann Debian-Maintainer ;).
-
-
Ohne den Artikel bereits komplett gelesen zu haben:
Danke, ganz sauberes Timing, ich bin gerade gestern in die Situation gelangt, Debian-Pakete schnüren zu müssen.
-
LordJaxom schrieb:
Ohne den Artikel bereits komplett gelesen zu haben:
Danke, ganz sauberes Timing, ich bin gerade gestern in die Situation gelangt, Debian-Pakete schnüren zu müssen.
Darf man fragen an was für Packeten du arbeitest?
-
Jetzt gerade brauche ich das xcfe4-modemlights-plugin für Ubuntu 7.10, für meinen eeePC. Das Paket ist übrigens fertig und funktioniert bereits. Es gibt aber artigerweise cdbs-rules für xfce4-plugins.
-
cdbs wäre interessant gewesen, aber der Artikel war fertig als ich mit cdbs angefangen habe
-
Nach dem Artikel ist vor dem Artikel