Haskell Packaging Guidelines
This page documents the guidelines and conventions for packaging Haskell projects in Fedora.
Spec file templates
Spec files in line with these templates are generated automatically by the cabal-rpm packaging tool which also adds dependencies listed in the package’s .cabal
configuration file. Most packages should then build, though for some packages it may be necessary to specify some additional BuildRequires and/or Requires, and to check non-Haskell devel dependencies.
Standardizing the packaging helps to lower the maintenance burden across Fedora’s Haskell packages.
There are three types of Haskell Cabal packages: library (Lib), binary only (Bin), and binary with library (BinLib):
Library Only
%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
Binary Only
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}
BinLib
%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
Package Naming
Haskell Bin packages should follow the usual Fedora Package Naming Guidelines for base package naming: i.e., follow the upstream name. Examples include projects like alex
and cabal-install
.
The names of Haskell Lib packages, packaged for ghc
, are prefixed by "ghc-". For example the Haskell aeson library package is named ghc-aeson
, and the Haskell X11 library package is named ghc-X11
, etc.
Haskell BinLib packages should be named like a Bin package if the most important part they provide is an executable (eg hlint
, ShellCheck
, and pandoc
), otherwise they should be named and packaged as a Lib package (eg ghc-hakyll
(has a setup executable), ghc-vty
(has demo executables)) if they are actually a library that includes an helper executable or demo or minor utility. In this case typically the executable should live in the devel subpackage (or maybe the library base package if it is used at runtime).
Note that having different Haskell source packages named "ghc-xyz" and "xyz" is not allowed since they would both correspond to the same upstream package named "xyz" on Hackage.
BinLib packages should subpackage their libraries with naming following Lib packages. For example the pandoc
BinLib package has library subpackages
-
ghc-pandoc
for the shared library, -
ghc-pandoc-devel
for devel files and the static library, -
ghc-pandoc-prof
for the profiling static library, -
ghc-pandoc-doc
for the library’s extracted development documentation.
If a library is packaged for more than one Haskell compiler or interpreter, the base name should instead be prefixed with haskell
, e.g. haskell-X11
. Such a package would then have subpackages for each compiler and/or interpreter it is built for (e.g. ghc-X11
, hugs98-X11`, etc).
Package naming preserves case to follow the upstream naming conventions as closely as possible, including package dependencies.
Headers
The macro pkg_name
is used to carry the name of the upstream library package (i.e. without the Fedora "ghc-" prefix). It should be defined at the top of Lib and BinLib packages:
+%global pkg_name +
Cabal Flags
If needed Cabal flags for build options should be set by changing the package’s .cabal
file: this can usually be done with the cabal-tweak-flag
script to avoid having to carry and maintain patches for this.
For example cabal-tweak-flag systemlib True
might enable a flag to use a system library dependency.
%cabal_configure_options
can be set to pass other options to Cabal.
Modifying the .cabal
file flags defaults allows packagers and tools like cabal-rpm
to track actual package dependencies correctly.
Dependencies
The cabal-tweak-dep-ver
script can used to change version bounds of dependencies in the package’s .cabal file: cabal-tweak-dep-ver deppkg oldbound newbound
eg: cabal-tweak-dep-ver base '< 4.16' '< 4.17'
Similarly cabal-tweak-drop-dep
for dropping a redundant dependency (eg a compatibility dummy package).
eg: cabal-tweak-drop-dep mtl-compat
Spec file build dependencies are generated by the cabal-rpm
packaging tool.
Binary RPM dependencies for Haskell libraries are automatically generated at build-time by the ghc-deps.sh
script.
Shared and static library linking
GHC uses static libraries for linking by default. Lib and BinLib packages should provide static, shared, and profiling libraries:
-
the shared library lives in the base library package,
-
the static library and interface development files in the -devel subpackage,
-
and the profiling library and profiling interface files in the -prof subpackage.
Since GHC assumes static versions of libraries are installed they need to be in the devel subpackage and it doesn’t make sense to subpackage them.
Executables in Bin and BinLib packages should be statically linked for portability.
RPM Macros
The templates all have buildrequires for ghc-rpm-macros, which provides macros.ghc to assist with packaging Haskell Cabal packages.
BuildRequires: ghc-rpm-macros
The main commonly used macros are:
-
%ghc_bin_build
-
%ghc_lib_build
-
%ghc_bin_install
-
%ghc_lib_install
They are used in the templates and explained in more detail below.
Bin packages
Executables are statically linked to Haskell libraries by default.
%build %ghc_bin_build %install %ghc_bin_install
%ghc_bin_build
is used to configure and build bin packages. It runs:
-
%cabal_configure
: configure the package for building and dynamic linking. -
%cabal build
: builds the package.
%ghc_bin_install
is used to install bin packages. It runs:
-
%cabal_install
: to install the package.
Lib and BinLib packages
Devel subpackages need to setup some Requires:
%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 packages need to use %setup -n
:
%prep %setup -q -n %{pkg_name}-%{version}
Both Lib and BinLib have:
%build %ghc_lib_build %install %ghc_lib_install
%ghc_lib_build
is used to configure, build and generate documentation for Lib and BinLib packages. It runs:
-
%cabal_configure --ghc -p
: configures the package for building with ghc and profiling. Libraries should build profiling versions of their static libraries. -
%cabal build
: builds the package. -
%cabal haddock
: generates HTML library documentationr from the source code.-
If documentation is failing to build for some reason,
%ghc_lib_build_without_haddock
can be used instead of%ghc_lib_build
to disable haddock generation.
-
%ghc_lib_install
is used to install Lib and BinLib packages. It runs:
-
%cabal_install
: installs the package without registering it in ghc-pkg. -
%cabal_pkg_conf
: creates ghc-pkg .conf metadata filer for package installation time -
%ghc_gen_filelists
: generates rpm filelists.
Debuginfo
Debuginfo is currently disabled for Haskell packages, because ghc’s Dwarf output is not very useful. Stack backtraces can also be generated using profiling libraries.
Directories
GHC libraries are installed under %ghclibdir/%{pkg_name}-%{version}
:
Library documentation lives under %ghclibdocdir/%{pkg_name}-%{version}
.
File lists
Filelists for shared and devel library subpackages are generated through %ghc_lib_install
using the macro %ghc_gen_filelists
.
It generates the filelists ghc-%{pkg_name}.files
, ghc-%{pkg_name}-devel.files
, ghc-%{pkg_name}-prof.files
, and ghc-%{pkg_name}-doc.files
.
Compiling non-Cabal packages
Packages compiling Haskell code without Cabal, i.e., directly with ghc
or ghc --make
, should use -O1
optimization, like Cabal does by default.
Want to help? Learn how to contribute to Fedora Docs ›