Debian Pakete bauen und kompilieren

Paketformat

Als Linux-Distribution muss die Software in Debian neben der ausführbaren Binärform i. A. auch als SourceCode vorliegen. Dazu gibt es auch zwei verschiedene Paketformate:
Binärpakete
Pakete mit der Endung .deb enthalten die erzeugten Binärdateien. Diese Dateien werden mit der Debian-Paketverwaltung dpkg installiert. Bei dem deb Paket handelt es sich um ein ar Archiv, dass wiederum zwei tar Archive enthält: Eines mit den zu installierenden Dateien (data.tar.gz) und eines mit den Kontroll-Informationen (control.tar.gz). Zusätzlich ist eine Datei mit Versions-Informationen enthalten (debian-binary).
Sourcepakete
Ein Source-Paket besteht aus drei Dateien: Der Debian Source Control Datei (.dsc), einem tar Archiv mit den orignalen ("upstream") Quellen (.orig.tar.gz) und einer gepackten Patch-Datei mit den Debian-spezifischen Anpassungen (.diff.gz).

Backports

Vorkompilierte Pakete aus der unstable-Distribution erwarten zumeist neuere Bibliotheken, als im System installiert sind. Um die Systemstabilität nicht zu mindern, sollten diese Pakete stattdessen aus den Quellen neukompiliert werden.

Um aus einem in der Debian-Distribution enthaltenen Source-Paket ein Binär-Paket zu bauen, sind im Idealfall die folgenden Schritte nötig:
  1. Für den Bau benötigte Pakete installieren:
    Dies erledigt das Kommando apt-get build-dep Paketname. (Zusätzlich muss noch das Meta-Paket DebPkg:build-essential installiert sein, dass für die Installation allgemein zum Bau von Binaries nötige Tools (Compiler, Linker, usw.) sorgt.
  2. Ein Repository mit Source-Paketen in die /etc/apt/sources.list eintragen, bspw.
    deb-src http://mirror.gsi.de/distrib/debian testing main
    Anschließend mit apt-get update die Informationen über die verfügbaren Pakete aktualisieren.
  3. Mit apt-get die Quellen herunterladen, entpacken, kompiliert und packen:
    Dazu dient das Kommando apt-get -b source Paketname. Nach dem Herunterladen und Entpacken der Quellen wird automatisch dpkg-buildpackage -b -uc aufgerufen, dass den eigentlichen Paketbau erledigt. (Ohne -b werden lediglich die Quelltexte heruntergeladen und entpackt.).
  4. Das Binärpaket installieren:
    dpkg -i Paketname_Versionsnummer_Plattform.deb.

Beispiel: apt-get -b source disktype baut das für Woody noch nicht verfügbare DebPkg:disktype Utility.

Probleme

Unerfüllbare build dependencies

Ansatz 1: Rekursiver backport

Beispiel: DebPkg:chkrootkit -> DebPkg:po-debconf -> DebPkg:intltool-debian

Ansatz 2: Paketabhängigkeiten ignorieren/ändern

Beispiel: Bau von chkrootkit mit -d

Sollte beim Installieren der build dependencies oder beim Bau etwas schiefgehen, kann man mit das Paket herunterladen und auspacken. Zunächst sollte man die Datei debian/control im Quelltextbaum untersuchen. Diese enthält die wichtigsten Informationen zu den vermeintlichen Abhängigkeiten. Der eigentliche Bau (configure, make, ...) und das Zusammenpacken der Dateien wird durch die Datei debian/rules gesteuert. Schließlich kann man mit dpkg-buildpackage -b -uc im Wurzelverzeichnis des entpackten Archives den Bau des Binärpaketes anstoßen.

Pakete nach Upload nicht sichtbar via apt-get

Falls Pakete nach dem Upload auf den Mirror weder im Home von debarchiver (/var/lib/debarchiver/incoming/...) liegen geblieben sind noch nach hinreichender Wartezeit und vielmaligem apt-get update sichtbar werden, ist das Paket vielleicht der Debian-Bürokratie zum Opfer gefallen.
  • Check: Paket liegt vielleicht in distrib/gsi-repository/dists/.../main/source/...?
Source Pakete sollten zwar keine =.deb=-Dateien sein, das interessiert den Debarchiver jedoch wenig. Falls der Dateiname des Pakets allerdings nicht dem speziellen Debian-Muster von Unterstrichen, Bindestrichen, Punkten und Nummer entspricht, wird das Paket gnadenlos als Source-Paket eingeordnet.

Don't despair! Not all is lost!

Lediglich der Name der Paket-Datei ist wichtig, es geht hier nur um Äußerlichkeiten. Daher kann ein Paket Name.deb in eine Debianpaketdatei verwandelt werden, indem man z.B. im Wissen, daß das Paket für 64bit Systeme bestimmt ist, zwischen Name und .deb einfach irgendeine Nummer (darf auch die Paketnummer sein) und ein amd64 einfügt, schon säuberlich durch Unterstriche getrennt: Name_2.304-2_amd64.deb Und schwups schluckt der Debarchiver die Datei und packt sie an die richtige Stelle.

Bau von Debian-Paketen für Perl-Module

Zum Bau von Debian-Paketen aus Perl-Packages vom CPAN gibt es das Tool Man:dh-make-perl. Dieses Tool ermöglicht, Perl-Module mit Hilfe der Debian-Paketverwaltung auf einem Rechnerhaufen zu verteilen, was mit Perl selbst nicht möglich ist, soweit mir bekannt ist. Um ein Debian-Paket für ein Perl-Modul zu erzeugen, reicht dh-make-perl --build --cpan Modulname. Der Paketbau funktioniert analog zur Verwendung des Perl-Moduls CPAN:Bundle::CPAN; es werden jedoch keine Abhängigkeiten beachtet, man muss also die Abhängigkeiten des Moduls herausfinden und die entsprechenden Pakete ebenfalls bauen.

Bau von Kernelpaketen

Siehe KernelBuild.

Wie man Debian-Pakete für Kernel-Module selbst baut

Paketbau aus Sourcen / Umwandlung mit alien

Tools

Paket-Umwandlung mit alien

Gut für Binärpakete, die debianisiert werden sollen. Beispiel: RAID-Controller-Software

  • Das Quellpaket, z.B. tw_cli-linux-x86_64-9.3.0.7.tgz, an einenm geeigneten Ort kopieren.
  • fakeroot alien -c -g tw_cli-linux-x86_64-9.3.0.7.tgz erzeugt zwei Verzeichnisse, tw_cli... und tw_cli....orig, die beide das ausgepackte Archiv enthalten. In ersterem erzeugt alien auch das Unterverzeichnis debian.
    • Die Option -c bringt alien dazu, die Start-Stop-Skripte mitzunehmen: die sind aber meistens nicht Debian-kompatibel und müssen angepaßt werden.
  • Im Unterverzeichnis debian finden sich die Dateien changelog  control  copyright  rules
  • Diese Dateien sind nach eigenem Gutdünken und/oder Maßgabe ähnlicher Paketbauten zu editieren.
  • In changelog notiert man, was man gerade zu tun beabsichtigt.
  • control dient der Debian-Paketverwaltung dazu festzustellen, wie das Paket heißt, in welches Archiv es gehört, was drin steckt usw.
  • rules ist das Makefile für den Paketbau:

debian/rules

  • export DH_COMPAT=4 ist aktuell offenbar eine nötige Angabe, die bei einem anderen Wert als 4 angemeckert wird.

  • dh_installinit Installiert debian/package.init nach /etc/init.d/package und erzeugt den nötigen Code zum Anlegen der /etc/rc?.d/ Links für debian/postinst.

  • Das von alien erzeugte rules enthält die Zeile
# Copy the packages's files.
        find . -maxdepth 1 -mindepth 1 -not -name debian -print0 | \ xargs -0 -r -i cp -a {} debian/$(PACKAGE)
  • Dieser Eintrag kann ersetzt werden, wenn die Zielverzeichnisse der einzelnen im Paket enthaltenen Dateien bekannt sind, im Beispiel des 3ware 3DM2 Pakets also:
        mkdir -p debian/tmp/html
        tar xfz 3dm-lnx.tgz -C debian/tmp
        cp debian/tmp/3dm2.x86_64 debian/$(PACKAGE)/usr/sbin/3dm2
        tar xfz debian/tmp/3dm-help.tgz -C debian/tmp/html

        cp -a debian/3dm2.conf debian/$(PACKAGE)/usr/share/3ware-dm2/
        cp -a debian/3dm2.conf debian/$(PACKAGE)/etc/3ware-dm2/

  • Die per Default auskommentierten Zeilen für dh_strip und dh_fixperms können offenbar aktiviert werden.

debian/Paketname.dirs
  • Damit wie oben im rule File angegeben die Dateien auch nach debian/$(PACKAGE)/... kopiert werden können, muß offenbar im debian Verzeichnis eine Datei Paketname.dirs erzeugt werden, die die Zielverzeichnisse ohne führenden Slash auflistet.

debian/postinst
  • In debian/postinst sollte ziemlich am Schluß eine Zeile #DEBHELPER# stehen (siehe ~christo/debian/sarge/3ware/3ware-dm2-9.3.0.7/debian/postinst). Und in debian/rules steht dh_installinit (siehe man dh_installinit).
  • *.debhelper (hier z.B. 3ware-dm2.postrm.debhelper) sollte es gar nicht geben, sondern beim Paketbau von ebenjenem erzeugt werden. Dann wird der Platzhalter #DEBHELPER# mit dem Inhalt der Datei ersetzt und diese kann in die Tonne (sollte debclean eigentlich übernehmen).
  • Sind hingegen beim Paketbau Dateien *.debhelper schon vorhanden, wird der Inhalt der Datei stattdessen offenbar angehängt. Im Falle von init - Dateien führt das dazu, daß der Start des Dienstes (hier 3dm2) als Abschluss der Installation des Pakets fehlschlägt.

Bau des Pakets
  • Mit fakeroot dpkg-buildpackage -b -uc kann schließlich das Binärpaket gebaut werden.

Debian-konformes patchen mit dpatch

Um in Debian-Paketen Dateien zu patchen, kann das Tool dpatch verwendet werden.

Nötige Änderungen an debian/rules:
  1. include /usr/share/dpatch/dpatch.make in die Preambel der Datei einfügen
  2. Das Ziel build (oder configure oder configure-stamp) vom Ziel patch (oder patch-stamp) abhängig machen: build: patch
  3. Das Ziel clean vom Ziel unpatch abhängig machen: clean: unpatch

Die anzuwendenden Patches müssen in debian/patches/ stehen werden und in der Datei debian/patches/00list aufgeführt werden.

Patches können "interaktiv" mit dpatch-edit-patch geschrieben werden.

Binärpaket aus Sourcen kompilieren

Geht mit dh_make und debuild.

http://wiki.debian.org/IntroDebianPackaging

http://www.debian.org/doc/manuals/maint-guide/index.en.html

  • aptitude install -r build-essential devscripts debhelper dh-make autotools-dev
  • Upstream-Tarball entpacken, ins entspr. Verzeichnis gehen.
  • dh_make -f ../paket.tar.gz fabriziert ../paket.orig.tar.gz und das debian - Unterverzeichnis
  • debian/changelog, debian/copyright, debian/control anpassen (s.o.)
  • debian/rules besteht anfangs nur aus
#!/usr/bin/make -f
%:
        dh $@
  • Den ./configure Teil des klassischen Dreisprungs kann man mit override_dh_auto_configure beeinflussen.
    • Bsp. robinhood:
 
 #!/usr/bin/make -f
override_dh_auto_configure:
        dh_auto_configure -- --with-purpose=TMP_FS_MGR --disable-tests --prefix=/usr
%:
        dh $@

    • Die eingerückten Zeilen fangen mit einem Tab an! Falls das resultierende Debian-Paket nur Readmes unter /usr/share enthält, ist vielleicht aus dem Tab eine Reihe von Spaces geworden, was zwar keine erkennbaren Fehlermeldung hervorruft, aber den ganzen Kompilierteil ausläßt und ein leeres Paket fabriziert.

  • Wenn es ein Init-Skript gibt, sollte es als debian/paket.init abgelegt ist und allen möglichen Debian- und LSB-Standards entsprechen.

  • debuild -us -uc

Paketbau aus Sourcen mit Hilfe von checkinstall

Mittels checkinstall lassen sich bei der Übersetzung und Installation von »Tarballs« gleich auch einfache Debian-Pakete erstellen. Dazu ist folgende Vorgehensweise ratsam:
  1. Falls notwendig Installation von checkinstall mit:
    apt-get install checkinstall
  2. Download des gewünschten Programmpaketes, etwa blafasel.tar.gz.
  3. Auspacken des Paketes nach /tmp mit:
    tar -xvzf blafasel.tar.gz -C /tmp
  4. Wechsel in das Paketverzeichnis mit:
    cd /tmp/blafasel
  5. Falls notwendig Installationshinweise (zumeist in den Dateien README oder INSTALL untergebracht) lesen.
  6. Falls notwendig erforderliche Entwicklerbibliotheken (zumeist libirgendwas-devel bezeichnet) installieren.
  7. Konfiguration durchführen mit:
    ./configure
    Hiermit werden eine oder mehrere Dateien namens Makefile erzeugt, die den Übersetzungsprozeß steuern. Ferner ist es an dieser Stelle möglich, den Installationsort anzupassen sowie bestimmte Funktionen des Programmpaketes ein- oder auszuschalten. Eine Übersicht der verfügbaren Schalter wird nach Eingabe von ./configure --help angezeigt.
  8. Der Compilerlauf wird angestoßen mit:
    make
    Je nach Rechnergeschwindigkeit und Paketumfang kann dieser Schritt einige Sekunden, aber auch einige Stunden dauern.
  9. Nun nicht wie gewohnt als "root" durch make install das Paket installieren, sondern gleichzeitig ein Debian-Paket daraus bauen mit:
    checkinstall make install
    Im folgenden Dialog lassen sich Paketparameter wie Name, Versions- und Releasenummer anpassen:
    *** Warning: The package version "blafasel" does not
    *** Warning: contain any digits. dpkg might not like that.

    This package will be built according to these values:

    0 - Maintainer: [ tux@linux.dom ]
    1 - Summary: [ Blafasel 1.0.1 for Debian Sarge ]
    2 - Name: [ blafasel ]
    3 - Version: [ blafasel ]
    4 - Release: [ 1 ]
    5 - License: [ GPL ]
    6 - Group: [ useless ]
    7 - Architecture: [ i386 ]
    8 - Source location: [ blafasel.tar.gz ]
    9 - Alternate source location: [ ]

    Enter a number to change any of them or press ENTER to continue: 3
    Enter new version:
    >> 1.0.1

    This package will be built according to these values:

    0 - Maintainer: [ tux@linux.dom ]
    1 - Summary: [ Blafasel 1.0.1 for Debian Sarge ]
    2 - Name: [ blafasel ]
    3 - Version: [ 1.0.1 ]
    4 - Release: [ 1 ]
    ...
  10. Das fertige Debian-Paket findet sich im aktuellen Verzeichnis, der Name setzt sich aus Paketname, Version und Release sowie Architektur zusammmen, hier also blafasel-1.0.1-1_i386.deb und kann nun verteilt werden.
In der Anwendung einfach, ist checkinstall allerdings auch in seiner Funktion limitiert. Laut M. F. Krafft in The Debian System (1. Auflage 2005, S. 241f) lassen sich so nur Dateien installieren, nicht jedoch bereits vorhandene Dateien während der Installation verändern. Ferner werden Konfigurationsdateien nicht als solche in der Paketdatenbank registriert, was zu Problemen bei Updates führen kann.

Beispiel: Debianpaket patchen

In diesem Beispiel wird gezeigt, wie man eine gepatchte Variante von DebPkg:gridengine-master unter Debian Squeeze erstellt, demonstrationshalber wollen wir lediglich die Datei sources/README.BUILD um eine Zeile mit dem Inhalt "Beispiel" erweitern. Der Ablauf sieht hierbei wie folgt aus:

  1. Build-Dependencies installieren: apt-get build-dep gridengine-master
  2. Helfer-Skripte zum Debian-Paketbau installieren: apt-get install devscripts
  3. Source Paket herunterladen und entpacken: cd; apt-get source gridengine-master
  4. Patch-Datei erstellen und diese in die Liste der anzuwnendenden Patches hinzufuegen. Hierzu kopiert man die zu patchende Datei z.B. nach /tmp und editiert sie. Anschliessend holt man sich mittels diff das passende Patch Format:
    1. cd ~/gridengine-6.2u5; cp source/README.BUILD /tmp/; echo Beispiel /tmp/README.BUILD
    2. diff -u source/README.BUILD /tmp/README.BUILD > debian/patches/095-testpatch.diff
    3. 095-testpatch.diff sieht nun in etwa so aus:
               --- source/README.BUILD   2010-06-06 18:20:07.000000000 +0200
               +++ /tmp/README.BUILD   2012-06-07 17:43:48.236646380 +0200
               @@ -327,3 +327,4 @@
                   Copyright: 2001 by Sun Microsystems, Inc.
              
                   All Rights Reserved.
               +Beispiel
      
               
    4. Die ersten beiden Zeilen ersetzt man mit:
            --- a/source/README.BUILD
            +++ b/source/README.BUILD
            
    5. Damit der Patch von quilt auch angewendet wird, tragen wir ihn noch in die Datei debian/patches/series ein: echo "095-testpatch.diff" >> debian/patches/series
  5. Debian Changelog bearbeiten. Hierzu ruft man dch -i auf, welches das Changelog mit $EDITOR oeffnet und die aktuelle Versionsnummer erhoeht. Ausserdem wird das Grundgeruest fuer den Changelog vorbereitet. Das ganze sieht dann fuer die neue Version z.B. so aus:
         gridengine (6.2u5-1squeeze1.1) squeeze-security; urgency=low
    
          * Non-maintainer upload.
          * 
    
           -- Vorname Nachname <user@localhost>  Thu, 07 Jun 2012 17:17:11 +0200
         
    An dieser Stelle kann man nun einige Dinge korrigieren, wie Name, E-Mail und auf jeden Fall was der Patch bewirken sollte, evtl. auch die Versionsnummer.
  6. Jetzt kann man das Paket mittels debuild -us -uc neu bauen. Anmerkung: Da fuer DebPkg:gridengine-master das Source-Paket auch fuer andere Pakete zustaendig ist, werden diese auch gebaut.


Siehe auch:

-- ChristopherHuhn, ThomasRoth, StefanHaller -- 2004 - 2007
Topic revision: r36 - 2015-03-23, ThomasRoth