Aus Linux-Magazin 02/2006

Distributionsunabhängige Pakete mit Autopackage

© sxc.hu

Obwohl sie nach dem gleichen Prinzip arbeiten, laufen RPMs von Suse 9.2 nicht unter Suse 9.3 und schon gar nicht unter Red Hat. Das Autopackage-Projekt setzt auf einen einheitlichen Standard für die Erstellung von Installationspaketen. Dabei lösen die einzelnen Pakete ihre Abhängigkeiten selbst auf.

Es ist ein Dilemma: Natürlich wollen die Entwickler kleiner Sourceforge-Projekte ihre Programme einer möglichst breiten Öffentlichkeit zugänglich machen, es fehlen ihnen aber meist die Ressourcen, um für jede der zahlreichen Linux-Distributionen eigene Pakete zu bauen. Sie müssen hoffen, dass ihr Programm Teil einer gängigen Distribution wird, um auch jene Nutzer zu erreichen, für die das Kompilieren des Quellcode nicht in Frage kommt.

Distributoren wie Suse, Red Hat oder Debian verfügen aber selbst nicht über die notwendigen offenen Kapazitäten, um alle Programme an die Bedürfnisse ihrer Distribution anzupassen – mitunter laufen nicht einmal die offiziell mitgelieferten Pakete problemlos.

Außerdem zeigen zunehmend kommerzielle Software-Anbieter Interesse daran, ihre Produkte auf dem Linux-Sektor zu vermarkten. Da sie häufig den Quellcode nicht freigeben wollen, stellen sie selbst Pakete her, jedoch nur für einige auserwählte Distributionen. Unter anderem deshalb beschloss der englische Informatikstudent Mike Hearn 2002 ein Paketsystem zu entwickeln, das über Distributionsgrenzen hinweg funktioniert – Autopackage [1].

Vorteile von Autopackage

Das ambitionierte Ziel besteht darin, die Verantwortung für das Erstellen der Setup-Programme den Entwicklern zu übertragen. Im Gegenzug emanzipieren sich die Projekte von der Release-Planung der Linux-Häuser: Jede neue Version steht sofort für die Benutzer zur Verfügung. Zudem profitiert Drittanbieter-Software von diesem System.

Auch Benutzerfreundlichkeit und Desktop-Integration kommen nicht zu kurz: Der Installationsprozess eines Pakets erfordert keine Interaktion mit dem Benutzer, ein übersichtlich gestaltetes grafisches Interface zeigt den Fortschritt des Setup an (Abbildung 1). Auch können Benutzer die Pakete ohne Kenntnis des Root-Passworts installieren: So ist es möglich, unbekannte oder in Entwicklung befindliche Pakete zu testen, ohne die Systemintegrität zu gefährden.

Die am weitesten verbreiteten Paketformate RPM und Deb sind für derartige Erweiterungen nicht flexibel genug, daher setzt Autopackage auf ein neues Paketkonzept. Die folgenden drei Punkte listen die wichtigsten Unterschiede zu den bekannten Systemen auf.

  • Vom System unabhängiger Dependency Check: Autopackage
    prüft – unabhängig von Distribution und verwendetem
    Paketmanager – während des Setup-Vorgangs die
    Abhängigkeiten der zu installierenden Software und lädt
    gegebenenfalls Pakete nach.
  • Skript-getriebene Installation: Ein Skript steuert den
    Setup-Vorgang. Es reagiert flexibel auf die Gegebenheiten des
    Zielsystems, um zum Beispiel Gnome-Komponenten unter Suse Linux
    nach »/opt/gnome« zu installieren.
  • Größtmögliche Portabilität: Autopackage
    selbst ist ebenfalls ein Shellskript und nutzt damit einige
    Vorteile des Bash-Interpreters. Der ist in praktisch allen
    Linux-Distributionen bereits standardmäßig vorhanden,
    Autopackage benötigt also keine zusätzliche
    Software.

Das standardisierte Paketformat erleichtert die Unterstützung für die heterogene Linux-Landschaft enorm, es gibt das Installationswerkzeug sowohl in GTK+ als auch in Qt-Ausführung. Ein entscheidender Unterschied zur traditionellen Paketverwaltung besteht in der dezentralen Bereitstellung der Pakete: Die Paketverteilung über die Linux-Distributoren entfällt, der Release-Prozess beschleunigt sich und neue Programmversionen stehen mit Autopackage unmittelbar für die Benutzer zur Verfügung.

Einschränkungen

Obwohl einige etablierte Open-Source-Projekte wie Abiword [2], Gaim [3] oder Inkscape [4] Autopackage erfolgreich einsetzen, gibt es Einschränkungen, die eine größere Verbreitung verzögern. So produziert die vor einiger Zeit freigegebene Version 4.0 des GNU-C++-Compilers Binärcode, der inkompatibel zu früheren Versionen ist, was zu scheinbar zufälligen Abstürzen führen kann.

Für Entwickler, die das C++-basierte Qt-Toolkit [5] verwenden – also mehr oder weniger die gesamte KDE-Community -, ist das wohl ein Hinderungsgrund, Autopackage zu nutzen. Die meisten GTK+-Programme [6] sind indes in C geschrieben, also bleiben die GTK+- und Gnome-Entwickler von diesem GCC-Problem verschont.

Eine weitere Schwierigkeit: Unter Umständen gehen Dateien verloren, wenn ein Benutzer ein installiertes Programm mit dem gleichnamigen Autopackage überschreibt: Die distributionseigenen Paketsysteme (RPM, DPKG) identifizieren die neuen Dateien fälschlich als ihre eigenen und entfernen sie im Zuge einer Deinstallation. Da das jeweils andere Paketsystem von der Deinstallation nichts weiß, betrachtet es das betreffende Paket als immer noch installiert.

Die Lösung für dieses Problem heißt NPMI (Native Package Manager Integration), also die Integration in die Paketdatenbank des Host-Systems. Es gibt bereits erste Patches, die während des Setup-Vorgangs die installierten Dateien in die RPM- oder DPKG-Datenbank eintragen und somit Inkonsistenzen zwischen dem Paketsystem des Hosts und Autopackage verhindern. Die Autopackage-Entwickler kennen das Problem und wollen es in künftigen Releases beheben [7].

Autopackage für Endanwender

Für die Benutzer ist der Umgang mit Autopackage einfach: Jedes Paket ist ein Shellskript und enthält in komprimierter Form auch das zu installierende Programm. Somit erfolgt das Setup eines Pakets nach dem Herunterladen über die Kommandozeile (zum Beispiel »bash abiword-2.4.1.x86.package« für Abiword) oder durch einen Doppelklick auf das Paket im Dateimanager. Es gibt zudem grafische Oberflächen für den Installationsprozess (Abbildung 1).

Abbildung 1: Die Fortschrittsanzeige während der Installation eines Pakets: Der Vorgang erfordert keine Interaktion mit dem Benutzer.

Abbildung 1: Die Fortschrittsanzeige während der Installation eines Pakets: Der Vorgang erfordert keine Interaktion mit dem Benutzer.

Beim Setup des ersten Pakets holt Autopackage automatisch den so genannten Support-Code aus dem Netz und installiert damit das eigentliche Autopackage-System. Mit der Angabe des Root-Passworts richtet der Benutzer Autopackage systemweit ein. Das geschieht ebenfalls über eine grafische Oberfläche – natürlich ist Autopackage aber auch über eine terminalbasierte Schnittstelle bedienbar. Die Installationsroutine läuft anschließend ohne jede weitere Interaktion mit dem Benutzer ab.

Das Hinzufügen weiterer Pakete funktioniert über einen Doppelklick auf ein Package oder über die Eingabe von »bash Programmname«. Daneben gibt es auch einen grafischen Paketmanager, der die Deinstallation von Programmen ermöglicht (Abbildung 2).

Abbildung 2: Der Autopackage-Manager deinstalliert Pakete benutzerfreundlich über eine grafische Oberfläche.

Abbildung 2: Der Autopackage-Manager deinstalliert Pakete benutzerfreundlich über eine grafische Oberfläche.

Portable Binärprogramme

Autopackages erstellt der Benutzer etwas anders als herkömmliche Pakete. Grundsätzlich sind dazu drei Schritte erforderlich:

  • Um die Präfix-Unabhängigkeit zu gewährleisten,
    müssen das Programm oder die Bibliothek unabhängig von
    dem Verzeichnis funktionieren, in das sie installiert wurden.
  • Der Packager muss den Prozess des Übersetzens anpassen,
    damit die Software plattformunabhängig arbeitet.
  • Das Autopackage-Format mit der typischen Dateinamen-Erweiterung
    ».package« ist notwendig, um die Kooperation mit dem
    Installationsprogramm zu gewährleisten.

Die folgenden Abschnitte beschreiben die Vorgehensweise anhand eines Pakets für das populäre Tabellenkalkulations-Programm Gnumeric [8]. Grundsätzlich liefert Autopackage aber jede beliebige Art Software aus.

Linux-Programme arbeiten im Unterschied zu gängigen Win32-Applikationen nicht Präfix-unabhängig. Das bedeutet, dass der vorgesehene Installationsort nach dem Übersetzen des Programms unveränderlich feststeht. Autopackages müssen aber unabhängig vom Verzeichnis auf dem Zielsystem laufen, daher bereitet man den Quellcode auf das Laden von Icons, Lokalisations-Dateien oder anderen mitgelieferte Dateien vor.

Hier hilft das Werkzeug Binreloc [9]. Da Autopackage bisher nur unter Linux funktioniert, es Gnumeric aber auch für andere Systeme wie Windows, Mac OS X und BSD gibt, müssen die Änderungen optional sein:

cp binreloc-2.0/binreloc.m4 gnumeric/
cd gnumeric/
export ACLOCAL_FLAGS="-I ."
./autogen.sh

Der Benutzer kopiert zunächst die im Binreloc-Paket enthaltene Makrodatei »binreloc.m4« ins Gnumeric-Quellcodeverzeichnis und fügt den Aufruf »AM_BINRELOC« in die Datei »configure.in« ein, bevor er »configure« neu erstellt. Fehlt die Datei »autogen.sh«, hängt er alternativ den Inhalt von »binreloc.m4« an die Datei »aclocal.m4« an und startet »autoconf«. Der Aufruf von »./configure –help« offenbart, ob der Parameter »–enable-binreloc« nun bereitsteht.

Vor dem Aufruf von »./configure« kommt der zusätzliche Quellcode von Binreloc ins Build-System. Da Gnumeric auf dem Glib-Objektsystem basiert, ist eine entsprechende Binreloc-Option notwendig. Auch für Qt-Programme steht eine ins Qt-Objektsystem integrierte Version zur Verfügung. Die neu entstandenen Quellcode- und Header-Dateien gehören ins Gnumeric-Verzeichnis:

cd binreloc-2.0/
./generate.pl glib
cp binreloc.c binreloc.h ../gnumeric/src

Um nun »binreloc.c« zu kompilieren, ist es nötig, die Datei »gnumeric/src/Makefile.am« gemäß Listing 1 zu ändern. Das Ergänzen der Präprozessor-Direktiven um »$(BINRELOC_CFLAGS)« aktiviert den zusätzlichen Code abhängig von der Build-Konfiguration. Die Headerdatei »binreloc.h« in die Vorlage für das Makefile einzubinden ist in diesem Fall nicht obligatorisch.

Listing 1:
»Makefile.am«

01 AM_CPPFLAGS =                       
02         -I$(top_srcdir)             
03         -I$(srcdir)                 
04         -I$(srcdir)/widgets         
05         -I$(srcdir)/dialogs         
06         -I$(srcdir)/tools           
07         $(BINRELOC_CFLAGS)          
08         $(GNUMERIC_CFLAGS)
09 
10 [...]
11 
12 GNUMERIC_BASE =                     
13         binreloc.c                  
14         binreloc.h                  
15         gnm-marshalers.list         
16         application.c               
17         application.h               

Quellcode ändern

Es folgt die eigentliche Modifikation des Quellcode. Da die Datei »gnumeric/src/gutils.c« alle Pfade gemeinsam verwaltet, kann die Anpassung zentral geschehen (Listing 2). Gnumeric lagert ab Version 1.6 die gesamte Programmlogik in eine Bibliothek aus, daher ist »gbr_init_lib()« für die Initialisierung von Binreloc erforderlich. Die Funktion »gbr_find_prefix()« ermittelt den Basisort der Installation, auf dem alle anderen Pfade aufbauen. Der abgeänderte Code überschreibt die vom Build-System erzeugten fixen Vorgaben mit dem Laufzeitpfad.

Listing 2:
»gutils.c«

01 #ifdef ENABLE_BINRELOC
02 #include "binreloc.h"
03 #endif
04 
05 #ifndef G_OS_WIN32
06 const char *gnumeric_lib_dir = GNUMERIC_LIBDIR;
07 const char *gnumeric_data_dir = GNUMERIC_DATADIR;
08 static const char *gnumeric_icon_dir = GNUMERIC_ICONDIR;
09 static const char *gnumeric_locale_dir = GNUMERIC_LOCALEDIR;
10 
11 ...
12 
13 void
14 gutils_init (void)
15 {
16         char const *home_dir;
17         gchar *dir = NULL;
18 #ifdef G_OS_WIN32
19         dir = g_win32_get_package_installation_directory (NULL, NULL);
20         priv_lib_dir = gnumeric_lib_dir = g_build_filename (dir,
21                 "lib", "gnumeric", GNUMERIC_VERSION, NULL);
22         priv_data_dir = gnumeric_data_dir = g_build_filename (dir,
23                 "share", "gnumeric", GNUMERIC_VERSION, NULL);
24         gnumeric_icon_dir = g_build_filename (dir,
25                 "share", "pixmaps", "gnumeric", NULL);
26         gnumeric_locale_dir = g_build_filename (dir,
27                 "share", "locale", NULL);
28         g_free (dir);
29 #elif defined ENABLE_BINRELOC
30         GError *error = NULL;
31         gbr_init_lib (&error);
32         if (error) {
33                 g_error ("Initialisierung von Binreloc fehlgeschlagen");
34         }
35         dir = gbr_find_prefix (NULL);
36         gnumeric_lib_dir = g_build_filename (dir,
37                 "lib", "gnumeric", GNUMERIC_VERSION, NULL);
38         gnumeric_data_dir = g_build_filename (dir,
39                 "share", "gnumeric", GNUMERIC_VERSION, NULL);
40         gnumeric_icon_dir = g_build_filename (dir,
41                 "share", "pixmaps", "gnumeric", NULL);
42         gnumeric_locale_dir = g_build_filename (dir,
43                 "share", "locale", NULL);
44         g_free (dir);
45 #endif 
46         home_dir = g_get_home_dir ();
47         gnumeric_usr_dir = (home_dir == NULL ? NULL :
48            g_build_filename (home_dir, ".gnumeric", GNUMERIC_VERSION, NULL));
49 
50         solver_max_time_err = _("The maximum time exceeded. The optimal "
51                                 "value could not be found in given "
52                                 "time.");
53 }

Nun schreitet der Paketmacher zur Tat und erstellt die Grundlage für das eigentliche Autopackage. Dazu benötigt er zunächst das Entwicklerpaket von Autopackage [10], um dann – ähnlich wie bei RPM-Paketen – die Vorlage für das Specfile zu schaffen. Das Programm »makeinstaller« erzeugt ein Template, das üblicherweise unter dem Namen »default.apspec.in« in das Unterverzeichnis »autopackage/« kommt. Der »makeinstaller« ist im zuvor installierten Entwicklerpaket von Autopackage enthalten:

cd gnumeric/
mkdir autopackage
cd autopackage/
makeinstaller --mkspec >default.apspec.in

Das eigentliche Specfile erzeugt der Paketbauer auf Basis dieser Vorlage. Um »automake«-Makros wie zum Beispiel »@VERSION@« zu verwenden, ergänzt er die Datei »configure.in« (Listing 3). Jeder Aufruf von »configure« generiert dann die Datei »autopackage/default.apspec« mit aktualisierten Versionsinformationen neu.

Listing 3: »Ausschnitt aus
gnumeric/configure.in«

01 AC_OUTPUT([
02 gnumeric.spec
03 Makefile
04 autopackage/default.apspec
05 icons/Makefile
06 src/Makefile

Paket bauen

Listing 4 zeigt, wie ein vorbereitetes Specfile aussehen sollte. Die Bereiche »[Meta]« und »[Description]« enthalten allgemeine Informationen, die während der Installation und im Managerprogramm erscheinen. Die Zusammenfassung im Abschnitt »[Description]« sollte ausführlich genug sein, um dem Benutzer ein klares Bild vom Zweck des Pakets zu vermitteln. Alle folgenden Abschnitte funktionieren wie Shellskripte, die beliebige Bash-Kommandos enthalten dürfen.

Listing 4:
»/autopackage/default.apspec.in«

01 [Meta]
02 RootName: @gnome.org/gnumeric:@VERSION@
03 DisplayName: Gnumeric Tabellenkalkulation
04 ShortName: gnumeric
05 Maintainer: The Gnumeric Developers
06 Packager: Robert Staudinger <robert.staudinger@gmail.com>
07 Summary: Gnumeric ist ein sehr umfangreiches Tabellenkalkulations-Programm
08 URL: http://www.gnome.org/projects/gnumeric/
09 License: GNU General Public License, Version 2
10 SoftwareVersion: @VERSION@
11 AutopackageTarget: 1.0
12 
13 [Description]
14 Gnumeric aims to become a drop in replacement for proprietary spreadsheets [...]
15 
16 [BuildPrepare]
17 # Erzeugen eines Hilfs-Skripts, welches configure aufruft.
18 # Damit wird es möglich das Paket ausserhalb des Quellcode-Verzeichnisses zu
19 # erstellen
20 if [ ! -e "configure" ] ; then
21         echo '#!/bin/bash' > configure
22         echo '../gnumeric/configure $@' >> configure
23         chmod +x configure
24 fi
25 prepareBuild --enable-binreloc
26 
27 [BuildUnprepare]
28 unprepareBuild
29 
30 [Imports]
31 echo '*' | import
32 
33 [Prepare]
34 require @xmlsoft.org/libxml2 2.4
35 require @gtk.org/gtk 2.6
36 require @glade.gnome.org/libglade 2.0
37 require @gnome.org/libgsf 113.0
38 
39 [Install]
40 installExe bin/*
41 installLib lib/*-*.*.*.so
42 installData share/*
43 
44 [Uninstall]
45 uninstallFromLog

»[BuildPrepare]« ist für das Kompilieren verantwortlich. Viele Entwickler nehmen den Build außerhalb des Quellcode-Verzeichnisses vor. Diese Funktionalität sieht Autopackage zwar selbst nicht vor, kann sie aber – wie das Specfile-Listing zeigt – implementieren. Das Skript gibt den Aufruf von »configure« in das Quellcodeverzeichnis weiter. Die in »prepareBuild« zugewiesenen Parameter erhält »configure« übergeben, anschließend startet automatisch »make«.

Endet die Übersetzung ohne Fehler, folgt die Installation in ein temporäres Verzeichnis. Der Abschnitt »[Imports]« legt dafür fest, welche Dateien aus der temporären Installation ins Paket kommen: Das Autopackage-Werkzeug »import« stellt eine Liste dieser Dateien auf, »echo \’*\’« bindet sie ein.

Der »[Prepare]«-Abschnitt bereitet die Installation vor. Im Fall von Gnumeric stellt er die Anwesenheit der wichtigen Bibliotheken sicher, wobei Skeletons zum Einsatz kommen. Diese Shellskripte überprüfen die Existenz von Bibliotheken oder beliebigen anderen Abhängigkeiten eines Programms. Autopackage bringt selbst eine Anzahl Skeletons mit. Es ist aber durchaus üblich, im Zuge einer Paketerstellung weitere zu schreiben und sie an die Autopackage-Entwickler weiterzugeben, damit sie Eingang in die künftigen Releases finden. Die URL der benötigten Software trägt der Paketbauer optional in das Skeleton ein.

Zusatzpakete nachladen

Ist beim Ausführen des Installers die Software nicht präsent, nutzt Autopackage diesen Link, um das Zusatzpaket herunterzuladen und zu installieren. Andernfalls bricht die Installation mit einer Fehlermeldung ab. Das Auflösen der Abhängigkeiten und den Download der Zusatzpakete setzten die Autopackage-Entwickler mit Hilfe von Code aus dem Projekt Luau [11] um.

Der »[Install]«-Bereich regelt das Verhalten während einer Installation. Eine Reihe von Befehlen hilft dabei (Tabelle 1), die Bestandteile einer Linux-Applikation an ihren vorgesehenen Ort zu kopieren. Autopackage zeichnet die Resultate ihrer Ausführung auf und kann so Fehlschläge während der Installation teilweise rückgängig machen. Dazu genügt der Aufruf von »uninstallFromLog« im abschließenden Sektor »[Uninstall]«. Nach Abschluss der Vorbereitungen generiert »./configure && makeinstaller« aus dem Specfile das Autopackage. Die Anweisung kompiliert den Quellcode erneut, was mitunter etwas dauert.

Tabelle 1:
Gültige Install-Befehle

 

Dateien

Befehl

Ausführbare Programme

installExe

Bibliotheken

installLib

Architekturunabhängige Daten

installData

Man-Seiten

installMan

Desktop-Dateien für Menü-Einträge

installDesktop

Desktop-Dateien für Mime-Zuordnungen

installMimeDesktop

Lokalisationsdateien

installLocale

Vorlagen zum Erkennen von Dateitypen

installMime

Icons

installIcon

Texinfo-Dateien

installInfo

Applikationsspezifische Konfigurationsdateien

installConfig

GConf-Schemas

installGConfSchema

Das fertige Paket »gnumeric-1.6.2.x86.package« lässt sich dann wie eingangs beschrieben installieren. Weitere Hilfe bei Problemen bietet die Autopackage-Webseite [1]: Vom Quickstart-Tutorial bis zum Packagers Guide stehen diverse Dokumentationen zur Verfügung, die den Einstieg ins Thema erleichtern.

Ausblick

Wie mehrere tausend Downloads jeder neuen Gaim- oder Inkscape-Version bestätigen, kommt Autopackage bei den Benutzern recht gut an. Bestehende Probleme bei C++-Software durch die Inkompatibilität des Compilers beziehungsweise der Standardbibliothek soll die Autopackage-Version 1.2 beheben, die sich gerade im Betastadium befindet. Die künftigen Autopackages enthalten sowohl Codeteile zur Unterstützung des neuen als auch des älteren ABI (Application Binary Interface) der C++-Standardbibliothek.

Ein besserer Komprimierungsalgorithmus soll längere Downloadzeiten durch größere Pakete verhindern, darüber hinaus überschreibt die Autopackage-Version durch die Installation von Paketen keine systemeigenen Dateien mehr, sondern bricht stattdessen den Setup-Vorgang ab. Damit entfiele ein weiterer Kritikpunkt an dem Paketsystem. Das friedliche Nebeneinander von systemspezifischen Packages und Autopackages sollte die Verwendung von Autopackage auch für Qt- und KDE-Projekte interessanter machen. (kki)

Infos

[1] Autopackage-Webseite: [http://autopackage.org]

[2] Abiword-Webseite: [http://abiword.org]

[3] Gaim-Webseite: [http://gaim.sourceforge.net]

[4] Inkscape-Webseite: [http://inkscape.org]

[5] Qt-Toolkit: [http://www.trolltech.com/products/qt/index.html]

[6] GTK+ The GIMP Toolkit: [http://gtk.org]

[7] Autopackage-Roadmap: [http://autopackage.org/schedule.html]

[8] Gnumeric Webseite: [http://www.gnome.org/projects/gnumeric/]

[9] Präfix-Unabhängigkeit unter Linux: [http://autopackage.org/docs/binreloc/]

[10] Autopackage-Devel-Paket: [http://autopackage.org/download-tools.html]

[11] Luau-Projekt: [http://luau.sourceforge.net]

Der Autor

Robert Staudinger hat sich nach dem Absolvieren der Fachhochschule für Telekommunikationstechnik in Salzburg der Informatik verschrieben. Neben seinem Studium verdient er seinen Lebensunterhalt mit der Erstellung von barrierefreien Internetseiten und verbringt einen Teil seiner Freizeit damit, bei Abiword und diversen anderen Gnome-Projekten mit ein paar Zeilen Code auszuhelfen.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben