Anhang A. Fortgeschrittene Paketierung

# Anhang A. Fortgeschrittene Paketierung

Die Überarbeitung dieser Anleitung mit aktualisierten Inhalten und weiteren praktischen Beispielen ist unter Guide for Debian Maintainers verfügbar. Bitte verwenden Sie diese neue Anleitung als primäre Anleitung.

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.

Es könnte sein, dass Sie die durch den Befehl dh_make erstellten Paketierungsvorlagedateien manuell bearbeiten müssen, um Punkte aus diesem Kapitel zu berücksichtigen. Der neuere Befehl debmake sollte diese Punkte besser berücksichtigen.

## A.1. Laufzeit-Bibliothek

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

- Debian Policy Manual, Kapitel 8 »Shared libraries«

- Debian Policy Manual, Kapitel 9.1.1 »File System Structure«

- Debian Policy Manual, Kapitel 10.2 »Libraries«

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 nutzen.

- 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 `lib`foo`.so`.`1`: `objdump -p lib`foo`.so.`1` | grep SONAME` [87]

- 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` [88]

- `lib`foo``1``: das Paket für die Laufzeitbibliothek `lib`foo`.so.`1`` mit der SONAME-ABI-Version `1`.[89]

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

- `lib`foo``1`-dbg`: das Fehlersuch-Symbol-Paket, das die Debugging-Symbole für das Laufzeitpaket `lib`foo``1`` enthält.

- `lib`foo`-dev`: das Entwicklungspaket, das die Header-Dateien usw. für die Laufzeitbibliothek `lib`foo`.so enthält.`1``.[91]

- Debian-Pakete sollten im Allgemeinen keine `*.la`-Libtool-Archive enthalten.[92]

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

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

## A.2. `debian/`Paket`.symbols` verwalten

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.[94] Sie sollten die folgenden primären Referenzen im Detail lesen:

- Debian Policy Manual, Kapitel 8.6.3 »The symbols system«[95]

- dh_makeshlibs(1)

- dpkg-gensymbols(1)

- dpkg-shlibdeps(1)

- deb-symbols(5)

Es folgt ein grobes Beispiel, wie das Paket `libfoo1` aus der Version `1.3` der Originalautoren mit der korrekten Datei `debian/libfoo1.symbols` zu erstellen ist:

- 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 `debian/libfoo1.symbols` paketiert worden war, erstellen Sie sie als Datei `symbols` von allen verfügbaren Binärpaketen des selben Laufzeitbibliotheksnamens, der den gleichen SONAME der Bibliothek enthält, beispielsweise Version `1.1-1` und `1.2-1`. [96]

        $ 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 korrekt aktualisierte `symbols`-Datei aus dem erstellten Binärpaket der Laufzeitbibliothek. [97]

      $ 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 die 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. [98]

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

## A.3. Multiarch

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:

- MultiarchSpec im Ubuntu Wiki (Originalautoren)

- Multiarch/Implementation im Debian Wiki (Debian-Situation)

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:[99]

Alter Pfad | I386-Multiarch-Pfad | Amd64-Multiarch-Pfad
--- | --- | ---
`/lib/` | `/lib/i386-linux-gnu/` | `/lib/x86_64-linux-gnu/`
`/usr/lib/` | `/usr/lib/i386-linux-gnu/` | `/usr/lib/x86_64-linux-gnu/`

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

- eine Bibliotheksquelle `lib`foo`-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`

Paket | Architecture: | Multi-Arch: | Paketinhalt
--- | --- | --- | ---
`lib`foo``1`` | any | same | die Laufzeitbibliothek, koinstallierbar
`lib`foo``1`-dbg` | any | same | die Debug-Symbole der Laufzeitbibliothek, koinstallierbar
`lib`foo`-dev` | any | same | die Laufzeitbibliothek-Header-Dateien usw., koinstallierbar
`lib`foo`-tools` | any | foreign | die Laufzeitunterstützungsprogramme, nicht koinstallierbar
`lib`foo`-doc` | all | foreign | die Dokumentationsdateien der Laufzeitbibliothek
``bar`` | any | foreign | die übersetzten Programmdateien, nicht koinstallierbar
``bar`-doc` | all | foreign | die Dokumentationsdateien für das Programm
``baz`` | all | foreign | die interpretierten Programmdateien

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`

## A.4. Erstellen eines Laufzeitbibliothekspakets

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

- `debian/control` aktualisieren

  - `Build-Depends: debhelper (>=10)` zum Quellpaketabschnitt hinzufügen

  - `Pre-Depends: ${misc:Pre-Depends}` für jedes Laufzeitbibliothekspaket hinzufügen

  - Fügen Sie den `Multi-Arch:`-Absatz zu jedem Binärpaketabschnitt hinzu.

- `debian/compat` auf »10« setzen

- Passen Sie für alle Paketierungsskripte die Pfade vom normalen `/usr/lib/` auf die Multiarch-Variante `/usr/lib/$(DEB_HOST_MULTIARCH)/` an.

  - Zuerst `DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)` in `debian/rules` aufrufen, um die Variable `DEB_HOST_MULTIARCH` zu setzen.

  - Ersetzen Sie in `debian/rules` `/usr/lib/` durch `/usr/lib/$(DEB_HOST_MULTIARCH)/`.

  - Falls `./configure` als Teil des Ziels `override_dh_auto_configure` in `debian/rules` verwandt wird, stellen Sie sicher, dass Sie es durch `dh_auto_configure --` ersetzen. [100]

  - Ersetzen Sie in `debian/`foo`.install`-Dateien alle Vorkommen von `/usr/lib/` durch `/usr/lib/*/`.

  - Erstellen Sie dynamisch durch Hinzufügen eines Skripts im Ziel `override_dh_auto_configure` in `debian/rules` Dateien wie `debian/`foo`.links` aus `debian/`foo`.links.in`.

        override_dh_auto_configure:
                dh_auto_configure
                sed 's/@DEB_HOST_MULTIARCH@/$(DEB_HOST_MULTIARCH)/g' \
                        debian/foo.links.in > debian/foo.links

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

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

## A.5. Natives Debian-Paket

Falls ein Paket nur für Debian oder möglicherweise nur für lokale Benutzung betreut wird, können seine Quellen alle Dateien aus `debian/*` enthalten. Es gibt zwei Möglichkeiten, dies 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 wäre der Arbeitsablauf für ein natives Debian-Paket:

- 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 mittels des Befehls dh_make wie folgt erstellen:

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

Dann werden das Verzeichnis `debian` und seine Inhalte genau wie in 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 aus 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.)

[87] Alternativ: `readelf -d lib`foo`.so.`1` | grep SONAME`

[88] Alternativ: `readelf -d lib`foo`.so.`1` | grep NEEDED`

[89] Siehe Debian Policy Manual, Kapitel 8.1 »Run-time shared libraries«.

[90] Siehe Debian Policy Manual, Kapitel 8.1.1 »ldconfig«.

[91] Siehe Debian Policy Manual, Kapitel 8.3 »Static libraries« und Debian Policy Manual, Kapitel 8.4 »Development files«.

[92] Siehe Debian wiki ReleaseGoals/LAFileRemoval.

[93] Siehe Debian-Wiki RpathIssue.

[94] Rückwärts-inkompatible ABI-Änderungen verlangen normalerweise von Ihnen, dass Sie den SONAME der Bibliothek und den Namen des Laufzeitbibliothekspakets in neue SONAMEN bzw. Namen ändern.

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

[96] Alle vorhergehenden Versionen eines Pakets sind unter 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`

[97] 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`

[98] Siehe Debian Policy Manual, Kapitel 8.6.2 »Shared library ABI changes«.

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

[100] 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 angibt, in den ausführbare Programme installiert werden, die von anderen Programmen (nicht von Benutzern) ausgeführt werden. Die Vorgabe von Autotools ist `/usr/libexec/`, die Debian-Vorgabe ist allerdings `/usr/lib/`.

Kapitel 9. Das Paket hochladen |  |