Paketbaurichtlinien für Haskell

Diese Seite dokumentiert die Richtlinien und Konventionen für das Paketieren von Haskell-Projekten in Fedora.

Der Glasgow Haskell Compiler (GHC) ist der aktuell am weitesten verbreitete Haskell-Compiler. Die meisten Haskell-Pakete werden auf Hackage veröffentlicht und nutzen das Paketverwaltungssystem Cabal. Daher konzentrieren sich die aktuellen Richtlinien hauptsächlich auf die Paketierung für GHC mit Cabal.

Spec-Dateivorlagen

Die Spec-Dateien gemäß diesen Vorlagen werden automatisch vom Paketierungswerkzeug cabal-rpm generiert. Dieses Werkzeug fügt auch die in der Konfigurationsdatei .cabal des Pakets aufgeführten Abhängigkeiten hinzu. Die meisten Pakete sollten sich anschließend bauen lassen. Bei einigen Paketen kann es jedoch erforderlich sein, zusätzliche „BuildRequires“ und/oder „Requires“ anzugeben und Nicht-Haskell-Entwicklungsabhängigkeiten zu prüfen.

Die Standardisierung der Paketierung trägt dazu bei, den Wartungsaufwand für die Haskell-Pakete von Fedora zu verringern.

Es gibt drei Arten von Haskell Cabal-Paketen: Bibliothek (Lib), nur Binärdatei (Bin) und Binärdatei mit Bibliothek (BinLib):

Nur Bibliotheken

%global pkg_name @PACKAGE@

Name:           ghc-%{pkg_name}
Version:        @VERSION@
Release:        1%{?dist}
Summary:        @SUMMARY@

License:        @LICENSE@
URL:            https://hackage.haskell.org/package/%{pkg_name}
Source:         https://hackage.haskell.org/package/%{pkg_name}-%{version}/%{pkg_name}-%{version}.tar.gz

BuildRequires:  ghc-Cabal-devel
BuildRequires:  ghc-rpm-macros
BuildRequires:  ghc-base-prof

%description
@DESCRIPTION@

%package devel
Summary:        Haskell %{pkg_name} library development files
Provides:       %{name}-static = %{version}-%{release}
Provides:       %{name}-static%{?_isa} = %{version}-%{release}
Requires:       ghc-compiler = %{ghc_version}
Requires:       %{name}%{?_isa} = %{version}-%{release}

%description devel
This package provides the Haskell %{pkg_name} library development files.


%package doc
Summary:        Haskell %{pkg_name} library documentation
BuildArch:      noarch

%description doc
This package provides the Haskell %{pkg_name} library documentation.


%package prof
Summary:        Haskell %{pkg_name} profiling library
Requires:       %{name}-devel%{?_isa} = %{version}-%{release}
Supplements:    (%{name}-devel and ghc-prof)

%description prof
This package provides the Haskell %{pkg_name} profiling library.


%prep
%setup -q -n %{pkg_name}-%{version}


%build
%ghc_lib_build


%install
%ghc_lib_install


%files -f %{name}.files
%license LICENSE


%files devel -f %{name}-devel.files


%files doc -f %{name}-doc.files
%license LICENSE


%files prof -f %{name}-prof.files

Nur Binärdateien

Name:           @PACKAGE@
Version:        @VERSION@
Release:        1%{?dist}
Summary:        @SUMMARY@

License:        @LICENSE@
URL:            https://hackage.haskell.org/package/%{name}
Source:         https://hackage.haskell.org/package/%{name}-%{version}/%{name}-%{version}.tar.gz

BuildRequires:  ghc-Cabal-devel
BuildRequires:  ghc-rpm-macros
BuildRequires:  ghc-base-static

%description
@DESCRIPTION@


%prep
%setup -q


%build
%ghc_bin_build


%install
%ghc_bin_install


%files
%license LICENSE
%{_bindir}/%{name}

Binärdateien und Bibliotheken

%global pkg_name @PACKAGE@

Name:           %{pkg_name}
Version:        @VERSION@
Release:        1%{?dist}
Summary:        @SUMMARY@

License:        @LICENSE@
URL:            https://hackage.haskell.org/package/%{name}
Source:         https://hackage.haskell.org/package/%{name}-%{version}/%{name}-%{version}.tar.gz

BuildRequires:  ghc-Cabal-devel
BuildRequires:  ghc-rpm-macros
BuildRequires:  ghc-base-prof

%description
@DESCRIPTION@


%package -n ghc-%{name}
Summary:        Haskell %{name} library

%description -n ghc-%{name}
This package contains the Haskell %{name} library.


%package -n ghc-%{name}-devel
Summary:        Haskell %{name} library development files
Requires:       ghc-compiler = %{ghc_version}
Requires:       ghc-%{name} = %{version}-%{release}

%description -n ghc-%{name}-devel
This package provides the Haskell %{pkg_name} library development files.


%package -n ghc-%{name}-doc
Summary:        Haskell %{pkg_name} library documentation
BuildArch:      noarch

%description -n ghc-%{name}-doc
This package provides the Haskell %{pkg_name} library documentation.


%package -n ghc-%{name}-prof
Summary:        Haskell %{pkg_name} profiling library
Requires:       ghc-%{name}-devel%{?_isa} = %{version}-%{release}
Supplements:    (ghc-%{name}-devel and ghc-prof)

%description -n ghc-%{name}-prof
This package provides the Haskell %{pkg_name} profiling library.


%prep
%setup -q


%build
%ghc_lib_build


%install
%ghc_lib_install


%files
%license LICENSE
%{_bindir}/%{name}


%files -n ghc-%{name} -f ghc-%{name}.files
%license LICENSE


%files -n ghc-%{name}-devel -f ghc-%{name}-devel.files


%files -n ghc-%{name}-doc -f ghc-%{name}-doc.files
%license LICENSE


%files -n ghc-%{name}-prof -f ghc-%{name}-prof.files

Paketbenennung

Haskell-Binärpakete sollten den üblichen Fedora-Paketbenennungsrichtlinien für Basispakete folgen, d.h. dem Upstream-Namen. Beispiele hierfür sind Projekte wie alex und cabal-install.

Die Namen der für ghc gepackten Haskell-Bibliothekspakete beginnen mit „ghc-“. Beispielsweise heißt das Haskell-aeson-Bibliothekspaket ghc-aeson, das Haskell-X11-Bibliothekspaket ghc-X11 usw.

Haskell-BinLib-Pakete sollten wie Bin-Pakete benannt werden, wenn ihr wichtigster Bestandteil eine ausführbare Datei ist (z. B. hlint, ShellCheck und pandoc). Andernfalls sollten sie als Lib-Pakete benannt und paketiert werden (z.B. ghc-hakyll, das eine Setup-Datei enthält, ghc-vty, das Demo-Dateien enthält), wenn es sich tatsächlich um eine Bibliothek handelt, die eine Hilfsdatei, eine Demo oder ein kleineres Dienstprogramm enthält. In diesem Fall sollte sich die ausführbare Datei typischerweise im Teilpaket devel befinden (oder gegebenenfalls im Basispaket der Bibliothek, falls sie zur Laufzeit verwendet wird).

Beachten Sie, dass es nicht zulässig ist, unterschiedliche Haskell-Quellpakete mit den Namen „ghc-xyz“ und „xyz“ zu haben, da beide dem gleichen Upstream-Paket mit dem Namen „xyz“ auf Hackage entsprechen würden.

BinLib-Pakete sollten ihre Bibliotheken in Unterpakete auslagern, deren Namen den Lib-Paketen entsprechen. Beispielsweise hat das BinLib-Paket pandoc folgende Bibliotheksunterpakete:

  • ghc-pandoc für die gemeinsam genutzte Bibliothek,

  • ghc-pandoc-devel für die -devel-Dateien und die statische Bibliothek,

  • ghc-pandoc-prof für die statische Profiling-Bibliothek,

  • ghc-pandoc-doc für die extrahierte Entwicklungsdokumentation der Bibliothek.

Wenn eine Bibliothek für mehr als einen Haskell-Compiler oder -Interpreter paketiert wird, sollte dem Basisnamen stattdessen haskell vorangestellt werden, z.B. haskell-X11. Ein solches Paket hätte dann Teilpakete für jeden Compiler bzw. Interpreter, für den es erstellt wurde (z.B. ghc-X11, hugs98-X11` usw.).

Bei der Paketbenennung wird die Groß-/Kleinschreibung beibehalten, um den Namenskonventionen des Upstream-Projekts so genau wie möglich zu folgen, einschließlich der Paketabhängigkeiten.

Header

Das Makro pkg_name dient dazu, den Namen des Upstream-Bibliothekspakets zu übertragen (d.h. ohne das Fedora-Präfix „ghc-“). Es sollte am Anfang der Pakete Lib und BinLib definiert werden:

+%global pkg_name +

Cabal-Flags

Falls erforderlich, sollten Cabal-Flags für Bauoptionen durch Ändern der .cabal-Datei des Pakets gesetzt werden. Dies kann in der Regel mit dem Skript cabal-tweak-flag erfolgen, um zu vermeiden, dass Patches dafür mitgeführt und gepflegt werden müssen.

Beispielsweise könnte cabal-tweak-flag systemlib True ein Flag aktivieren, um eine Systembibliotheksabhängigkeit zu nutzen.

Mit %cabal_configure_options können weitere Optionen an Cabal übergeben werden.

Durch die Bearbeitung der Standardeinstellungen in der Datei .cabal können Paketierer und Werkzeuge wie cabal-rpm die tatsächlichen Paketabhängigkeiten korrekt verfolgen.

Abhängigkeiten

Das Skript cabal-tweak-dep-ver kann verwendet werden, um die Versionsgrenzen von Abhängigkeiten in der .cabal-Datei des Pakets zu ändern: cabal-tweak-dep-ver deppkg alte-grenze neue-grenze

Beispiel: cabal-tweak-dep-ver base '< 4.16' '< 4.17'

Analog dazu dient cabal-tweak-drop-dep zum Entfernen einer redundanten Abhängigkeit (zum Beispiel eines Kompatibilitäts-Dummy-Pakets).

Beispiel: cabal-tweak-drop-dep mtl-compat

Die Bauabhängigkeiten der Spec-Datei werden vom Paketierungswerkzeug cabal-rpm erzeugt.

Binäre RPM-Abhängigkeiten für Haskell-Bibliotheken werden automatisch zur Bauzeit durch das Skript ghc-deps.sh generiert.

Linken gemeinsam genutzter und statischer Bibliotheken

GHC verwendet standardmäßig statische Bibliotheken zum Verlinken. Die Lib- und BinLib-Pakete sollten statische, dynamische und Profiling-Bibliotheken bereitstellen:

  • die gemeinsam genutzte Bibliothek im Basis-Bibliothekspaket,

  • die statische Bibliothek und die Entwicklungsdateien der Schnittstelle im -devel-Teilpaket

  • und die Profiling-Bibliothek und die Profiling-Schnittstellendateien im -prof-Teilpaket.

Da GHC davon ausgeht, dass statische Versionen der Bibliotheken installiert sind, müssen diese im Teilpaket „-devel“ enthalten sein. Es ergibt keinen Sinn, sie in ein separates Teilpaket auszulagern.

Ausführbare Dateien in Bin- und BinLib-Paketen sollten aus Portabilitätsgründen statisch gelinkt sein.

Da GHC gemeinsam genutzte Bibliotheken mit --no-as-needed verlinkt, werden viele rpmlint-Fehler der Form `E: undefined-non-weak-symbol`erzeugt. Dies ist derzeit leider zu erwarten (siehe diese upstream issues).

RPM-Makros

Alle Vorlagen haben „BuildRequires:“ für ghc-rpm-macros, welches macros.ghc bereitstellt, um das Paketieren von Haskell Cabal-Paketen zu erleichtern.

BuildRequires:  ghc-rpm-macros

Die wichtigsten, am häufigsten verwendeten Makros sind:

  • %ghc_bin_build

  • %ghc_lib_build

  • %ghc_bin_install

  • %ghc_lib_install

Sie werden in den Vorlagen verwendet und nachfolgend detaillierter erklärt.

Bin-Pakete

Ausführbare Dateien sind standardmäßig statisch gegen Haskell-Bibliotheken gelinkt.

%build
%ghc_bin_build


%install
%ghc_bin_install

%ghc_bin_build dient zum Konfigurieren und Erstellen von Binärpaketen. Folgendes wird ausgeführt:

  • %cabal_configure: konfiguriert das Paket für die Erstellung und dynamische Verlinkung.

  • %cabal build: baut das Paket.

%ghc_bin_install wird verwendet, um Binärpakete zu installieren. Folgendes wird ausgeführt:

  • %cabal_install: installiert das Paket.

Lib- und BinLib-Pakete

Für -devel-Teilpakete müssen einige „Requires“ gesetzt werden:

%package -n ghc-%{pkg_name}-devel
Summary:        Haskell %{pkg_name} library development files
Requires:       ghc-compiler = %{ghc_version}
Requires:       ghc-%{pkg_name} = %{version}-%{release}

Lib-Pakete benötigen %setup -n:

%prep
%setup -q -n %{pkg_name}-%{version}

Sowohl Lib als auch BinLib haben:

%build
%ghc_lib_build


%install
%ghc_lib_install

%ghc_lib_build dient zum Konfigurieren, Erstellen und Generieren der Dokumentation für Lib- und BinLib-Pakete. Folgendes wird ausgeführt:

  • %cabal_configure --ghc -p: konfiguriert das Paket für die Erstellung mit GHC und Profiling. Bibliotheken sollten Profiling-Versionen ihrer statischen Bibliotheken erstellen.

  • %cabal build: baut das Paket.

  • %cabal haddock: erzeugt Bibliotheksdokumentation im HTML-Format aus dem Quellcode.

    • Falls die Dokumentation aus irgendeinem Grund nicht erstellt werden kann, kann %ghc_lib_build_without_haddock anstelle von %ghc_lib_build verwendet werden, um die Haddock-Generierung zu deaktivieren.

%ghc_lib_install wird verwendet, um Lib- und BinLib-Pakete zu installieren. Folgendes wird ausgeführt:

  • %cabal_install: installiert das Paket ohne Registrierung in ghc-pkg.

  • %cabal_pkg_conf: erstellt die ghc-pkg .conf Metadaten-Datei für die Installationszeit des Pakets

  • %ghc_gen_filelists: erzeugt rpm-Dateilisten.

Debuginfo

Debuginfo ist derzeit für Haskell-Pakete deaktiviert, da die Dwarf-Ausgabe von ghc wenig hilfreich ist. Stack-Backtraces können auch mithilfe von Profiling-Bibliotheken generiert werden.

Verzeichnisse

GHC-Bibliotheken werden unter %ghclibdir/%{pkg_name}-%{version} installiert:

Die Bibliotheksdokumentation befindet sich unter %ghclibdocdir/%{pkg_name}-%{version}.

Dateilisten

Dateilisten für gemeinsam genutzte und Entwicklungsbibliotheks-Teilpakete werden durch %ghc_lib_install unter Verwendung des Makros %ghc_gen_filelists generiert.

Es erzeugt die Dateilisten ghc-%{pkg_name}.files, ghc-%{pkg_name}-devel.files, ghc-%{pkg_name}-prof.files und ghc-%{pkg_name}-doc.files.

Kompilieren von Nicht-Cabal-Paketen

Pakete, die Haskell-Code ohne Cabal kompilieren, d.h. direkt mit ghc oder ghc --make, sollten die -O1-Optimierung verwenden, wie es Cabal standardmäßig tut.