Anhang A. Fortgeschrittene Paketierung

Inhaltsverzeichnis

A.1. Laufzeit-Bibliothek
A.2. debian/Paket.symbols verwalten
A.3. Multiarch
A.4. Erstellen eines Laufzeitbibliothekspakets
A.5. Natives Debian-Paket

Es folgen einige Tipps und Verweise für fortgeschrittene Paketierungsfragen, mit denen Sie wahrscheinlich zu tun bekommen werden. Es wird Ihnen nachdrücklich empfohlen, alle hier vorgeschlagenen Referenzen zu lesen.

Bevor Sie Laufzeit-Bibliotheken paketieren, sollten Sie die folgenden Referenzen im Detail lesen:

Es folgen einige stark vereinfachte Tipps für den Anfang.

  • Laufzeitbibliotheken (engl. »shared libraries«) sind ELF-Objektdateien, die übersetzten Code enthalten.

  • Laufzeitbibliotheken werden als *.so-Dateien vertrieben, d.h. weder als *.a- noch als *.la-Dateien.

  • Laufzeitbibliotheken werden hauptsächlich benutzt, um gemeinsamen Programmcode aus mehreren Programmen mittels des ld-Mechanismus gemeinsam zu benutzen.

  • Laufzeitbibliotheken werden manchmal dazu benutzt, mehrere Erweiterungen eines Programms mittels des dlopen-Mechanismus bereitzustellen.

  • Laufzeitbibliotheken exportieren Symbole, die übersetzte Objekte wie Variablen, Funktionen und Klassen darstellen und darauf Zugriff von dem verlinkten Programm ermöglichen.

  • Der SONAME einer Laufzeitbibliothek libfoo.so.1: objdump -p libfoo.so.1 | grep SONAME [89]

  • Der SONAME einer Laufzeitbibliothek passt typischerweise (aber nicht immer) auf den Dateinamen der Bibliothek.

  • Der SONAME von Laufzeitbibliotheken, die nach /usr/bin/foo gelinkt sind: objdump -p /usr/bin/foo | grep NEEDED [90]

  • libfoo1: das Bibliothekspaket für die Laufzeitbibliothek libfoo.so.1 mit der SONAME-ABI-Version 1.[91]

  • Die Paketbetreuerskripte des Bibliothekspakets müssen ldconfig unter den bestimmten Randbedingungen aufrufen, um die notwendigen symbolischen Links für den SONAME zu erzeugen.[92]

  • libfoo1-dbg: das Fehlersuch-Symbol-Paket, das die Debugging-Symbole für das Laufzeitpaket libfoo1 enthält.

  • libfoo-dev: das Entwicklungspaket, das die Header-Dateien usw. für die Laufzeitbibliothek libfoo.so enthält.1.[93]

  • Debian-Pakete sollten im Allgemeinen keine *.la-Libtool-Archive enthalten.[94]

  • Debian-Pakete sollten im Allgemeinen keinen RPATH enthalten.[95]

  • Obwohl sie etwas veraltet und nur Sekundärliteratur ist, könnte der Debian Library Packaging Guide noch nützlich sein.

Wenn Sie eine Laufzeitbibliothek paketieren, sollten Sie eine Datei debian/Paket.symbols erstellen, um die minimale Version zu verwalten, die jedem Symbol für rückwärts-kompatible ABI-Änderungen unter dem gleichen SONAME der Bibliothek für den gleichen Laufzeitbibliotheksnamen zugeordnet ist.[96] Sie sollten die folgenden primären Referenzen im Detail lesen:

Es folgt ein grobes Beispiel, um das Paket libfoo1 für die Version 1.3 der Originalautoren mit der korrekten Datei debian/libfoo1.symbols zu erstellen.

  • Bereiten Sie das Gerüst des debianisierten Quellbaums mit der Datei der Originalautoren libfoo-1.3.tar.gz vor.

    • Falls dies das erstmalige Paketieren des Pakets libfoo1 ist, erstellen Sie die Datei debian/libfoo1.symbols mit leerem Inhalt.

    • Falls die vorherige Version 1.2 der Originalautoren im Paket libfoo1 mit der korrekten debian/libfoo1.symbols in seinem Quellpaket paketiert war, verwenden sie diese wieder.

    • Falls die vorhergehende Version 1.2 der Originalautoren nicht mit der debian/libfoo1.symbols paketiert worden war, erstellen Sie sie als Datei symbols von allen verfügbaren Binärpaketen des selben Laufzeitbibliotheknamens, der den gleichen SONAME der Bibliothek enthält, beispielsweise Version 1.1-1 und 1.2-1. [98]

      $ dpkg-deb -x libfoo1_1.1-1.deb libfoo1_1.1-1
      $ dpkg-deb -x libfoo1_1.2-1.deb libfoo1_1.2-1
      $ : > symbols
      $ dpkg-gensymbols -v1.1 -plibfoo1 -Plibfoo1_1.1-1 -Osymbols
      $ dpkg-gensymbols -v1.2 -plibfoo1 -Plibfoo1_1.2-1 -Osymbols
      
  • Bauen Sie mit Werkzeugen wie debuild und pdebuild versuchsweise den Quellbaum. (Falls das aufgrund fehlender Symbole usw. fehlschlägt, gibt es einige rückwärtsinkompatible ABI-Änderungen, die es notwendig machen, den Paketnamen der Laufzeitbibliothek auf etwas wie libfoo1a zu erhöhen. Sie sollten dann wieder von vorne anfangen.)

    $ cd libfoo-1.3
    $ debuild
    ...
    dpkg-gensymbols: Warnung: einige neue Symbole sind in der Symboldatei aufgetaucht: …
     lesen Sie die folgende Diff-Ausgabe
    --- debian/libfoo1.symbols (libfoo1_1.3-1_amd64)
    +++ dpkg-gensymbolsFE5gzx        2012-11-11 02:24:53.609667389 +0900
    @@ -127,6 +127,7 @@
      foo_get_name@Base 1.1
      foo_get_longname@Base 1.2
      foo_get_type@Base 1.1
    + foo_get_longtype@Base 1.3-1
      foo_get_symbol@Base 1.1
      foo_get_rank@Base 1.1
      foo_new@Base 1.1
    ...
    
  • Falls Sie wie oben den von dpkg-gensymbols ausgegebenen Diff sehen, extrahieren Sie die korrekte symbols-Datei aus dem erstellten Binärpaket der Laufzeitbibliothek. [99]

    $ cd ..
    $ dpkg-deb -R  libfoo1_1.3_amd64.deb libfoo1-tmp
    $ sed -e 's/1\.3-1/1\.3/' libfoo1-tmp/DEBIAN/symbols \
            >libfoo-1.3/debian/libfoo1.symbols
    
  • Bauen Sie mit Werkzeugen wie debuild und pdebuild Veröffentlichungspakete.

    $ cd libfoo-1.3
    $ debuild clean
    $ debuild
    …
    

Zusätzlich zu den obigen Beispielen müssen wir die ABI-Kompatibilität weiter prüfen und die Versionen für einige Symbole wo notwendig erhöhen. [100]

Obwohl es nur eine nachrangige Referenz ist, könnte Debian wiki UsingSymbolsFiles und die darin verlinkten Webseiten hilfreich sein.

Die Multiarch-Funktionalität, die mit Debian Wheezy eingeführt wurde, unterstützt die architekturübergreifende Installation von Binärpaketen (insbesondere i386<->amd64, aber auch andere Kombinationen) in dpkg und apt. Sie sollten die folgenden Referenzen im Detail lesen:

Es verwendet ein Triplet wie i386-linux-gnu und x86_64-linux-gnu für den Installationspfad der Laufzeitbibliotheken. Der tatsächliche Triplett-Pfad wird durch dpkg-architecture(1) für jeden Bau dynamisch in $(DEB_HOST_MULTIARCH) gesetzt. Beispielsweise werden die Pfade zu Multiarch-Bibliotheken wie folgt geändert:[101]

Es gibt einige typische Beispiele für Multiarch-Paketaufteilungsszenarien:

  • eine Bibliotheksquelle libfoo-1.tar.gz

  • eine in einer übersetzten Sprache geschriebene Werkzeugquelle bar-1.tar.gz

  • eine in einer interpretierten Sprache geschriebene Werkzeugquelle baz-1.tar.gz

Beachten Sie, dass die Entwicklungspakete einen Symlink für die zugehörige Laufzeitbibliothek ohne eine Versionsnummer enthalten sollten. Z.B. /usr/lib/x86_64-linux-gnu/libfoo.so -> libfoo.so.1

Sie können ein Debian-Laufzeitbibliothekspaket mit Unterstützung von Multiarch mit dh(1) wie folgt bauen:

Bitte stellen Sie sicher, dass das Laufzeitbibliothekspaket nur die erwarteten Dateien enthält und dass Ihr -dev-Paket noch funktioniert.

Alle Dateien, die simultan in das Multiarch-Paket in den gleichen Dateipfad installiert werden sollten exakt den gleichen Inhalt haben. Sie müssen vorsichtig mit Unterschieden sein, die durch die generierte Byte-Reihenfolge und den Kompressionsalgorithmus sind.

Falls ein Paket nur für Debian oder möglicherweise nur für lokale Benutzung betreut wird, kann seine Quellen alle Dateien aus debian/* enthalten. Es gibt zwei Möglichkeiten, es zu paketieren.

Sie können einen Tarball der Originalautoren erstellen, bei dem Sie die debian/*-Dateien ausschließen und es als nicht natives Debian-Paket wie in Abschnitt 2.1, „Arbeitsschritte beim Bau von Debian-Paketen“ paketieren. Dies ist die normale Art, zu der einige Leute raten.

Die Alternative ist der Arbeitsablauf des nativen Debian-Pakets.

  • Erstellen Sie ein natives Debian-Quellpaket im Format 3.0 (native) mit einer einzelnen komprimierten Tar-Datei, in der alle Dateien enthalten sind.

    • Paket_Version.tar.gz
    • Paket_Version.dsc
  • Bauen Sie Debian-Binärpakete aus den nativen Debian-Quellpaketen.

    • Paket_Version_Arch.deb

Falls Sie beispielsweise Quelldateien in ~/mypackage-1.0 ohne die debian/*-Dateien haben, können Sie ein natives Debian-Paket dafür mittels des Befehl dh_make wie folgt erstellen:

$ cd ~/MeinPaket-1.0
$ dh_make --native

Dann werden das Verzeichnis debian und seine Inhalte genau wie bei Abschnitt 2.8, „Das erste nicht native Debian-Paket“ erstellt. Dies erstellt keinen Tarball, da dies ein natives Debian-Paket ist. Das ist aber auch der einzige Unterschied. Der Rest der Paketierungsaktivitäten ist praktisch identisch.

Nach der Ausführung des Befehls dpkg-buildpackage werden Sie die folgenden Dateien im übergeordneten Verzeichnis finden:

  • meinpaket_1.0.tar.gz

    Dies ist der Quellcode-Tarball, der von dem Verzeichnis MeinPaket-1.0 durch den Befehl dpkg-source erstellt wurde. (Seine Endung ist nicht orig.tar.gz.)

  • meinpaket_1.0.dsc

    Dies ist eine Zusammenfassung der Inhalte des Quellcodes, wie in dem nicht nativen Debian-Paket. (Es gibt keine Debian-Revision.)

  • meinpaket_1.0_i386.deb

    Dies ist Ihr komplettes Binärpaket wie in dem nicht nativen Debian-Paket. (Es gibt keine Debian-Revision.)

  • meinpaket_1.0_i386.changes

    Diese Datei beschreibt wie in dem nicht nativen Debian-Paket alle Änderungen, die in der aktuellen Paketversion erfolgten. (Es gibt keine Debian-Revision.)



[89] Alternativ: readelf -d libfoo.so.1 | grep SONAME

[90] Alternativ: readelf -d libfoo.so.1 | grep NEEDED

[96] Rückwärts-inkompatible ABI-Änderungen verlangen normalerweise von Ihnen, dass Sie den SONAME der Bibliothek und des Laufzeitbibliothekspakets auf den neuen ändern.

[97] Für C++-Bibliotheken und anderen Fällen, bei denen das Nachverfolgen individueller Symbole zu schwierig ist, folgen Sie stattdessen dem Debian Policy Manual, Kapitel 8.6.4 »The shlibs system«.

[98] Alle vorhergehenden Versionen eines Pakets sind von http://snapshot.debian.org/ erhältlich. Die Debian-Revision wird von der Version entfernt, um das Rückportieren eines Paketes zu erleichtern: 1.1 << 1.1-1~bpo70+1 << 1.1-1 and 1.2 << 1.2-1~bpo70+1 << 1.2-1

[99] Die Debian-Revision wird von der Version entfernt, um das Rückportieren eines Paketes zu erleichtern: 1.3 << 1.3-1~bpo70+1 << 1.3-1

[101] Alte Spezialbibliothekspfade wie /lib32/ und /lib64/ werden nicht mehr benutzt.

[102] Alternativ können Sie die Argumente --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) und --libexecdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) zu ./configure hinzufügen. Beachten Sie, dass --libexecdir den Standardpfad, in den ausführbare Programme, die von anderen Programmen (im Gegensatz zu Benutzern) ausgeführt werden, angibt. Die Vorgabe von Autotools ist /usr/libexec/, die Debian-Vorgabe ist allerdings /usr/lib/.