Debian-Pakete erstellen: Unterschied zwischen den Versionen

Aus /usr/space Wiki
Zur Navigation springen Zur Suche springen
(Artikel 'Debian-Pakete hosten' verlinkt)
 
Zeile 33: Zeile 33:
   |
   |
   └── usr/
   └── usr/
       └── local/
       └── bin/
           └── bin/
           └── hallo-welt
              └── hallo-welt


== Minimaler Aufbau des Arbeitsverzeichnisses für ein Source-Paket ==
== Minimaler Aufbau des Arbeitsverzeichnisses für ein Source-Paket ==

Aktuelle Version vom 30. August 2023, 19:34 Uhr

Dieser Artikel soll eine kurze Einführung über den Aufbau und die Erstellung von Debian-Binary-Paketen als auch -Source-Paketen liefern. Es wird hier nur auf die Grundlagen eingegangen, für eine ausführliche Erklärung verweise ich auf https://www.debian.org/doc/manuals/maint-guide/ .

Ein Binary-Paket kann direkt installiert werden. Auch wenn der Ausdruck Binary-Paket (oder Binärpaket) impliziert, dass ein kompiliertes Programm enthalten ist, muss das nicht der Fall sein. Ein Binärpaket kann auch nur Skripte enthalten, wodurch es nicht an eine bestimmte Hardware-Architektur gebunden sein muss.

Ein Source-Paket (oder Quellpaket) enthält den Quellcode und die Bauanweisungen für ein oder mehrere Binary-Pakete.

Namenskonvention

Die Konvention für den Paketnamen ist: paketname_[epoch:]version[-revision]_architektur. Die zwei Unterstriche (_) trennen Paketname, Version und Architektur. Klicke hier für Details und hier speziell für die Versionsnummer.

  • paketname: Der Name des Paketes
  • epoch (Versionsschema - optional): Falls sich das Versionierungsschema ändert (z.B.: Änderung von Datums- (bspw. YYYYMMDD) zu Semantic-Versioning (<MAJOR>.<MINOR>.<PATCH>) oder Fehler in der alten Versionierung), kann eine Versionsnummer - praktisch begonnen bei 1 (da 0 angenommen wird, wenn nicht angegeben - in dem Fall war die Angabe von epoch nicht notwendig) - gefolgt von einem Doppelpunkt (:) als Präfix für die Version verwendet werden. Somit wird sichergestellt, dass eine neue Version auch als aktueller interpretiert werden kann, wenn sich das Schema ändert.
  • version: Eine vergleichbare Zeichenkette, welche die Unterscheidung von älteren zu neueren Versionen erlaubt.
  • revision (optional): Wenn z.B. ein (fremdes) existierendes Projekt verpackt wird, auf das ein Patch angewendet wird, für den es (noch) keine neue Upstream-Version gibt oder geben wird, wird als Suffix ein Bindestrich (-) gefolgt von einer Zahl an die Version angefügt. Praktisch wird auch hier wieder bei 1 begonnen, da ohne Angabe 0 impliziert wird.
  • architektur: z.B.: armhf, arm64, amd64 oder all

Minimaler Aufbau des Arbeitsverzeichnisses für ein Binary-Paket

Das Arbeitsverzeichnis sollte gemäß der #Namenskonvention benannt werden.

Neben den Dateien, die schlussendlich auf dem Zielsystem installiert werden sollen, ist nur eine einzige Steuerdatei notwendig (siehe #DEBIAN/control (Binary-Pakete)): control. Diese Datei (und eventuelle weitere Steuerdateien und Metadaten) muss in <ARBEITSVERZEICHNIS>/DEBIAN/ liegen. Die restlichen Dateien müssen einfach in einer Struktur abgelegt werden, die das Root-Verzeichnis des Zielsystems relativ im Arbeitsverzeichnis darstellt.

Ein Beispiel:

 hallo-welt_1.0_all/
 |
 ├── DEBIAN/
 |   └── control
 |
 └── usr/
     └── bin/
         └── hallo-welt

Minimaler Aufbau des Arbeitsverzeichnisses für ein Source-Paket

Das Arbeitsverzeichnis eines Source-Paketes braucht zwar mehr Steuerdateien als ein Binary-Paket, allerdings ist hier im Wesentlichen nur die Struktur des debian-Unterordners wichtig, da die Installationspfade durch das Buildsystem bestimmt werden. Zu beachten ist, dass im Gegensatz zum Binary-Paket debian kleingeschrieben wird.

Ein Beispiel:

 helloworld-1.0/
 |
 ├── debian/
 |   ├── changelog
 |   ├── control
 |   ├── rules
 |   └── source/
 |       └── format
 |
 ├── Makefile
 └── helloworld.c

Control Files

DEBIAN/control (Binary-Pakete)

Im Folgenden sind Felder aufgelistet, welche in der control-Datei für Binary-Pakete aufgeführt werden können. Die Datei darf nur einen Abschnitt (keine Leerzeilen zwischen den Feldern) enthalten. Wenn nicht anders angegeben, sind die Felder optional (abweichende Anforderungen für offizielle Debian-Repos und vollständige Liste). Durch fehlende empfohlene Felder wird - solange nicht mit einem Asterisk (*) markiert - eine Warnung ausgegeben. Für eine Beschreibung der Felder siehe Abschnitt #Beschreibung der control-Datei-Felder.

DEBIAN/control Beispiel

Package: hallo-welt
Version: 1.0
Architecture: all
Maintainer: Your Name <your-email@example.com>
Section: misc
Priority: optional
Description: Ein einfaches Hallo Welt Bash-Programm

debian/control (Source-Pakete)

Im Folgenden sind Felder aufgelistet, welche in der control-Datei für Source-Pakete aufgeführt werden können. Die Datei muss mindestens zwei durch Leerzeilen getrennte Abschnitte enthalten, wovon der erste das Source-Paket beschreibt und die anderen jeweils ein Binary-Paket. Wenn nicht anders angegeben, sind die Felder optional (abweichende Anforderungen für offizielle Debian-Repos und vollständige Liste). Durch fehlende empfohlene Felder wird - solange nicht mit einem Asterisk (*) markiert - eine Warnung ausgegeben. Für eine Beschreibung der Felder siehe Abschnitt #Beschreibung der control-Datei-Felder.

Substitutionsvariablen

Substitutionsvariablen sind Platzhalter, die während des Bauprozesses eines Debian-Pakets durch bestimmte Werte ersetzt werden. Sie werden in der debian/control-Datei und anderen Dateien im debian/-Verzeichnis verwendet, um Informationen dynamisch einzufügen, die erst während des Bauprozesses bekannt sind. Dies kann die Automatisierung erleichtern und die Wartung von Paketen vereinfachen.

Hier sind einige gebräuchliche Substitutionsvariablen:

  • ${shlibs:Depends}: Diese Variable wird durch die Liste der Shared Library-Abhängigkeiten ersetzt, die ein Binärpaket benötigt. Das dh_shlibdeps-Tool liest die dynamisch gelinkten Bibliotheken des Binärpakets und ermittelt die benötigten Abhängigkeiten.
  • ${misc:Depends}: Dies wird durch eine Liste von Abhängigkeiten ersetzt, die von den im Paket verwendeten Debhelper-Tools ermittelt werden.
  • ${perl:Depends}: Wird in Perl-Paketen verwendet und enthält Abhängigkeiten, die von den Perl-Modulen ermittelt werden, auf die das Paket angewiesen ist.
  • ${python3:Depends}: Für Python 3-Pakete wird dies durch die erforderlichen Abhängigkeiten für die im Paket verwendeten Python 3-Module ersetzt.

Diese und andere Substitutionsvariablen werden von verschiedenen Debhelper-Tools verarbeitet und ersetzt. Sie machen es einfacher, korrekte Abhängigkeiten zu definieren, ohne dass sie manuell gepflegt werden müssen.

debian/control Beispiel

Source: hallo-welt
Section: misc
Priority: optional
Maintainer: Your Name <your-email@example.com>
Standards-Version: 3.9.8
Build-Depends:
  debhelper (>= 11),
  debhelper-compat (= 13),
  gcc,
  make

Package: hallo-welt
Architecture: any
Depends:
  ${shlibs:Depends},
  ${misc:Depends}
Description: Ein einfaches Hallo Welt C-Programm

Beschreibung der control-Datei-Felder

Package

Abschnitt in der aktuellen Debian-Policy. Der Name des Binary-Paketes.

Version

Abschnitt in der aktuellen Debian-Policy. Siehe #Namenskonvention bzw Link.

Architecture

Abschnitt in der aktuellen Debian-Policy. Eine durch Leerzeichen getrennte Liste der unterstützen Architekturen. Hier ein paar Beispiel-Architekturen (eine Liste aller bekannten Architekturen kann mittels dpkg-architecture -L ausgegeben werden; für Platzhalter siehe man dpkg-architecture):

  • any: Nur in Source-Paketen erlaubt. Der Source-Code ist plattformunabhängig, im gebauten Binary-Paket wird die tatsächliche Architektur aufgeführt. Es ist keine weitere Angabe erlaubt.
  • all: Das (ev. aus dem Source-Paket zu bauende) Binary-Paket ist plattformunabhängig (weil z.B. nur Skripte oder Dokumente enthalten sind). Es ist keine weitere Angabe erlaubt.
  • i386, amd64, armel, armhf, arm64, ppc64el, s390x, mips, mipsel, mips64el (usw.):
    • Ein Binary-Paket muss die Architektur aufweisen, für die es gebaut wurde (bzw. all, falls es plattformunabhängig ist.)
    • In der control-Datei eines Source-Paketes können - falls das entsprechende Paket nicht für alle Plattformen gebaut werden lann - je Package-Abschnitt die Architektur(en) angegeben werden, auf denen das Paket gebaut werden kann.
  • Wildcards: Siehe Manpage zu dpkg-architecture; Suchausdrücke Debian architecture wildcard, Debian architecture tuple

Maintainer

Abschnitt in der aktuellen Debian-Policy. Name und E-Mail-Adresse des Paket-Betreuers im Format Max Mustermann <max.mustermann@example.com>. Falls es sich um eine Gruppe handelt, siehe Uploaders.

Description

Abschnitt in der aktuellen Debian-Policy. Dieses Feld kann mehrere Zeilen umfassen und besteht aus einer Kurzbeschreibung und einer optionalen Langbeschreibung des Paketes. Die erste Zeile bildet die Kurzbeschreibung. Die weiteren Zeilen müssen mit einem Leerzeichen beginnen, wobei ein Leerzeichen gefolgt von einem Punkt ( .) die einzige Möglichkeit ist, eine Leerzeile auszudrücken. Zeilen, die mit einem Leerzeichen beginnen, müssen mindestens ein 'Nicht-Whitespace-Zeichen' enthalten. Tabs sollten nicht verwendet werden.

Ein Beispiel:

Description: gibt 'Hallo Welt!' aus.
 Ein revolutionäres Programm, das folgende Sachen kann:
  - 'Hallo Welt!' printen
  - sich danach beenden
 .
 Weil die Beschreibung so umfangreich ist, muss ein zweiter Absatz her ;-)

Section

Abschnitt in der aktuellen Debian-Policy. Wenn angegeben, sollte hier ein Wert aus den Standardsektionen eingetragen werden. Prinzipiell darf man aber auch Werte erfinden, allerdings können Paketverwaltungswerkzeuge besser mit Standardsektionen umgehen (z.B. nach Sektionen filtern).

Beispiele: games, net, admin, graphics, misc

Priority

Abschnitt in der aktuellen Debian-Policy. Im Regelfall ist dieser Wert auf optional zu setzen. Er gibt die Wichtigkeit des Paketes für ein Debian-System an (ob es z.B. in einer Installation unbedingt (required) enthalten sein muss; weitere Infos).

Depends

Abschnitt in der aktuellen Debian-Policy. Hier müssen alle Pakete aufgelistet werden, welche zur Verwendung bzw. Konfiguration dieses Paketes notwendig sind. Eine Installation des Paketes kann nur dann durchgeführt werden, wenn diese Abhängigkeiten erfüllt werden können.

Build-Depends

Abschnitt in der aktuellen Debian-Policy. Abhängigkeiten, welche zum Bauen des Paketes erfüllt sein müssen. Die Abhängigkeiten von Depends müssen nicht zum Bauen erfüllt sein. Hier kann auch die debhelper-Kompatibilitätsstufe festlegt werden, z.B.: debhelper-compat (= 13) (siehe Abschnitt #debian/compat)

Installed-Size

Abschnitt in der aktuellen Debian-Policy. Dieser Wert wird automatisch ermittelt, wenn ein Paket aus einem Source-Paket gebaut wird (darf also nicht in einem Source-Paket aufgeführt werden). Falls man ein Paket z.B. mittels dpkg-deb --build baut, muss dieser Wert selbst ermittelt werden (das Feld ist optional und kann auch weggelassen werden): es muss der Platzbedarf in Kilobytes (aufgerundet auf die nächste Ganzzahl) des installierten Paketes angegeben werden.

Homepage

Abschnitt in der aktuellen Debian-Policy. Hier kann die Projekt-Homepage - idealerweise wo der Quellcode zu finden ist (z.B. github) - aufgeführt werden.

Source

Abschnitt in der aktuellen Debian-Policy. In einem Binary-Paket kann hier der Name des Source-Paketes angegeben werden, wenn dieser vom Namen des Binary-Paketes abweicht. In einem Source-Paket muss dieses Feld im ersten Abschnitt enthalten sein (siehe Abschnitt #debian/control (Source-Pakete)).

Standards-Version

Abschnitt in der aktuellen Debian-Policy. Dieses Feld gibt die Version der Debian Policy an, nach welcher man sich bei der Erstellung des Paketes gerichtet hat. Um relativ schnell prüfen zu können, ob sich diese Version erhöhen lässt, kann man einen Blick in die Upgrade-Checklist werfen. Auch wenn man ein Paket außerhalb der offiziellen Debian-Repos betreut, ist es Best Practice, sich nach der möglichst aktuellen Policy zu richten.

Verhältnisse zwischen Paketen

Für Felder wie z.B. Breaks oder Conflicts siehe https://www.debian.org/doc/debian-policy/ch-relationships.html .

debian/compat

Diese Datei enthält nur eine Zeile mit einer Zahl, welche die debhelper-Kompatibilitätsstufe festlegt.

Diese Datei sollte in aktuellen Projekten nicht mehr benutzt werden - stattdessen sollte im Build-Depends-Feld der control-Datei debhelper-compat (= 13) aufgeführt werden (v13 ist der aktuell empfohlene Modus - siehe man debhelper-compat-upgrade-checklist).

debian/changelog

Änderungen an einem Paket sollten kurz im Changelog aufgeführt werden. Paket-Building-Tools ermitteln durch diese Datei auch gewisse Daten automatisch, z.B. die Paket-Version.

Nachfolgend das Schema mit Beispiel für einen Changelog-Eintrag (blauer Text ist als Kommentar zu verstehen):

[Paketname (Paketversion) Distribution(en); urgency=Dringlichkeit für ein Paketupgrade]

hallo-welt (1.0) stable; urgency=low --[jede Zeile der Änderungsdetails muss mit (mindestens) 2 Leerzeichen beginnen]   [optionale Leerzeilen vor den Änderungsdetails werden ignoriert]   * Änderungsdetails     weitere Änderungsdetails   [Leerzeilen mitten im Changelog bleiben in der Ausgabe von dpkg-parsechangelog erhalten]   * noch mehr Änderungsdetails   [optionale Leerzeilen nach den Änderungsdetails werden ignoriert] -[1 space][2 dashes][1 space][name <mail>][2 spaces][Datum im RFC 5322 Format - ${date -R}]  -- Max Mustermann <max.mustermann@example.com> Fri, 18 Aug 2023 11:00:00 +0200

 [optionale Leerzeilen nach dem Changelog-Eintrag werden ignoriert]
  • Paketname und code|Paketversion: siehe Abschnitte #Package und #Version.
  • Distribution(en): die Zielverteilung für das Paket, z.B. unstable, stable, testing oder ein spezifischer Codename wie buster oder bullseye. Ich persönlich trage hier die Repository-Komponente ein, in welcher das Paket hochgeladen wird (z.B. stable oder testing).
  • urgency: wie dringend ein Upgrade des Pakets auf diese Version ist (low, medium, high, emergency und critical sind die Werte, die von Debian benutzt werden - auch wenn man für sein eigenes Repo hier die Freiheit hat, neu zu benamsen, sollte man sich nach dieser Konvention richten). Optional kann hier auch ein Kommentar angegeben werden, welches nach einem Leerzeichen aufgeführt wird und konventionell in Klammern steht. Beispiel:
    • urgency=low (high, wenn Feature XY benutzt wird).
  • Änderungsdetails: jede Zeile der Änderungsdetails muss mit mindestens zwei Leerzeichen beginnen. Konventionell beginnt man einen Punkt der Details mit einem Asterisk (*). Leerzeilen, welche in diesem Bereich vorkommen, bleiben in der Ausgabe von dpkg-parsechangelog erhalten.
  • Betreuer, E-Mail-Adresse und Datum: die Formatierung dieser Zeile muss genauso sein, wie im Beispiel oben. Der aktuelle Zeitpunkt im richtigen Format (RFC 5322) kann per date -R ausgegeben werden.

Neue Einträge müssen oben (am Anfang) der Datei eingefügt werden.

debian/rules

Abschnitt in der aktuellen Debian-Policy. Diese Datei ist das zentrale Makefile, das den Bau des Paketes steuert. Im Regelfall ist es ausreichend, von dieser Datei einfach dh (debhelper) aufrufen zu lassen - Hier ein Beispiel:

#!/usr/bin/make -f

%:
	dh $@

Der Shebang ist unbeding erforderlich. Die -f-Option ist erforderlich, dass make diese Datei als Makefile behandelt.

In dem Minimalbeispiel wird einfach für alle Targets dh mit dem Target als Argument aufgerufen - dh ist ein Sequenzer, der abhängig von diesem Argument ein bestimmtes debhelper-Programm aufruft. Somit spart man sich das Erstellen der Targets, die von dpkg-buildpackage gerufen werden (z.B.: clean, binary, build). Um das Verhalten der debhelper-Programme steuern zu können, lassen sich dafür entsprechende Targets definieren (in der Form override_dh_<command>). Hier ein Beispiel:

override_dh_auto_configure:
ifeq ($(DEB_HOST_ARCH), amd64)
	dh_auto_configure -- --extra-ding-bei-amd64
else
	dh_auto_configure
endif

Um etwas einfach vor oder nach einem debhelper-Befehl auszuführen, gibt es die Targets execute_before_<dh_command> und execute_after_<dh_command>. Falls bei einem 'Nicht-dh_*'-Target ein bestimmtes Verhalten gewünscht wird, ist dieses Target einfach explizit anzugeben. Als Beispiel:

binary:
	echo "Hallo vor binary"
	dh $@
	echo "Hallo nach binary"

Weitere Infos zu dh sind der dh-Manpage (man dh) zu entnehmen.

Als nützliche Info sei hier noch erwähnt, wie man hier die Paketversion als Umgebungsvariable für seine Build-Umgebung zur Verfügung stellen kann:

export MY_DEB_VERSION=$(shell dpkg-parsechangelog -S Version)

debian/source/format

Diese Datei enthält nur eine Zeile, in welchem das Format des Source-Paketes angegeben wird.

Die zwei aktuell relevanten Formate sind:

  • 3.0 (quilt): Wenn eine Patch-Verwaltung notwendig ist, um Änderungen zum Upstream-Code zu verwalten, muss dieses Format gewählt werden
  • 3.0 (native): Sollte für Pakete verwendet werden, deren Quellcode speziell für Debian geschrieben wurde, und deshalb keine Patch-Verwaltung braucht.

Bilden eines Binary-Paketes

Eine Schritt-für-Schritt Anleitung findet sich in Beispiel: Bau eines Debian-Binärpaketes.

Bilden eines Source-Paketes

Eine Schritt-für-Schritt Anleitung findet sich in Beispiel: Bau eines Debian-Quellpaketes.

Pakete im eigenen Repository hosten

Eine Schritt-für-Schritt Anleitung findet sich in Debian-Pakete hosten.