Haskell Packaging Guidelines
This page documents the guidelines and conventions for packaging Haskell projects in Fedora.
GHC (Glasgow Haskell Compiler) is the current mainstream Haskell compiler. Most Haskell packages are released on Hackage and use the Cabal package system. So the current guidelines mostly focus on packaging for GHC using Cabal.
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 only (Lib), binary only (Bin), and binary and library (BinLib):
Library Only
%global pkg_name @PACKAGE@ Name: ghc-%{pkg_name} Version: @VERSION@ Release: 1%{?dist} Summary: @SUMMARY@ License: @LICENSE@ URL: http://hackage.haskell.org/package/%{pkg_name} Source0: http://hackage.haskell.org/packages/archive/%{pkg_name}/%{version}/%{pkg_name}-%{version}.tar.gz BuildRequires: ghc-Cabal-devel BuildRequires: ghc-rpm-macros %description @DESCRIPTION@ %package devel Summary: Haskell %{pkg_name} library development files Requires: ghc-compiler = %{ghc_version} Requires(post): ghc-compiler = %{ghc_version} Requires(postun): ghc-compiler = %{ghc_version} Requires: %{name} = %{version}-%{release} %description devel This package provides the Haskell %{pkg_name} library development files. %prep %setup -q -n %{pkg_name}-%{version} %build %ghc_lib_build %install %ghc_lib_install %post devel %ghc_pkg_recache %postun devel %ghc_pkg_recache %files -f %{name}.files %license LICENSE %files devel -f %{name}-devel.files %changelog * @DATE@ Fedora Haskell SIG <haskell@lists.fedoraproject.org> - spec file generated by cabal-rpm
Binary Only
Name: @PACKAGE@ Version: @VERSION@ Release: 1%{?dist} Summary: @SUMMARY@ License: @LICENSE@ URL: http://hackage.haskell.org/package/%{name} Source0: http://hackage.haskell.org/packages/archive/%{name}/%{version}/%{name}-%{version}.tar.gz BuildRequires: ghc-Cabal-devel BuildRequires: ghc-rpm-macros %description @DESCRIPTION@ %prep %setup -q %build %ghc_bin_build %install %ghc_bin_install %files %license LICENSE %{_bindir}/%{name} %changelog * @DATE@ Fedora Haskell SIG <haskell@lists.fedoraproject.org> - spec file generated by cabal-rpm
Library and Binary
%global pkg_name @PACKAGE@ Name: %{pkg_name} Version: @VERSION@ Release: 1%{?dist} Summary: @SUMMARY@ License: @LICENSE@ URL: http://hackage.haskell.org/package/%{name} Source0: http://hackage.haskell.org/packages/archive/%{name}/%{version}/%{name}-%{version}.tar.gz BuildRequires: ghc-Cabal-devel BuildRequires: ghc-rpm-macros %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(post): ghc-compiler = %{ghc_version} Requires(postun): ghc-compiler = %{ghc_version} Requires: ghc-%{name} = %{version}-%{release} %description -n ghc-%{name}-devel This package provides the Haskell %{pkg_name} library development files. %prep %setup -q %build %ghc_lib_build %install %ghc_lib_install %post -n ghc-%{name}-devel %ghc_pkg_recache %postun -n ghc-%{name}-devel %ghc_pkg_recache %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 %changelog * @DATE@ Fedora Haskell SIG <haskell@lists.fedoraproject.org> - spec file generated by cabal-rpm
Package Naming
Haskell Bin and BinLib packages should follow the usual Fedora Package Naming Guidelines for base package naming: ie follow the upstream name. Examples include projects like darcs
and xmonad
.
However there may be cases where a Haskell BinLib package is really a Lib package with a minor or unimportant executable: in this case it is better to treat the package a Lib package, optionally with a executable subpackage if appropriate.
The names of Haskell Lib packages, packaged for ghc
, are prefixed by "ghc-". For example the Haskell X11 library package is named ghc-X11
, and the Haskell mmap library package is named ghc-mmap
, etc.
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 xmonad
BinLib package has library subpackages
-
ghc-xmonad
for the shared library, and -
ghc-xmonad-devel
for devel files and the static library.
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.
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
Cabal flags for build options should be set by changing the package’s .cabal
file: this can be done with the cabal-tweak-flag
script to avoid having to carry and maintain patches for this.
%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.
Dependency Generation
Spec file build dependencies are generated by the cabal-rpm
packaging tool.
RPM dependencies for Haskell libraries are automatically generated at build-time by the ghc-deps.sh
script.
The cabal-tweak-dep-ver
script can be used to bump versions of dependencies in the package .cabal file.
Shared and static library linking
GHC uses static libraries by default, but supports shared libraries on some architectures: currently i686 and x86_64. Lib and BinLib packages should provide static, shared, and profiling libraries:
-
the shared library lives in the base library package, and
-
the static and profiling library and header files in the -devel subpackage.
Because GHC still assumes static versions of libraries are installed they need to be in the devel subpackage and it doesn’t make sense to subpackage them yet.
Executables in Bin and BinLib packages should be dynamically linked to shared libraries.
Note that executables in most BinLib packages are currently staticly linked against the library in their own package (unless the .cabal file explicitly lists it as a dependency), but dynamically linked against other dependent libraries. BinLib executables that do link dynamically against their own library should use %ghc_fix_dynamic_rpath
to fix its RPATH.
Some particular packages may do user compilation during runtime in which case they will need Requires as well as BuildRequires for their dependencies: examples include xmonad and yi which require their devel package to be present to allow users to relink their configuration or customization.
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
Bin package executables should be dynamically linked to shared Haskell libraries when available, but this can be overridden if necessary by defining the ghc_without_dynamic
macro.
%build %ghc_bin_build %install %ghc_bin_install
%ghc_bin_build
is used to configure and build bin packages. It runs:
-
%global debug_package %{nil}
: debuginfo is disabled since ghc’s output is not in GDB format. -
%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
: installs the package. -
%ghc_strip_dynlinked
: strips the dynamically linked binary.
Lib and BinLib packages
BinLib package executables should be dynamically linked to other shared Haskell libraries when available, but this can be overridden if necessary by defining the ghc_without_dynamic
macro.
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(post): ghc-compiler = %{ghc_version} Requires(postun): 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 %post devel %ghc_pkg_recache %postun devel %ghc_pkg_recache
%ghc_lib_build
is used to configure, build and generate documentation for Lib and BinLib packages. It runs:
-
%global debug_package %{nil}
: debuginfo is disabled since ghc’s output is not in DWARF format. -
%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 documentation from the source code.-
If necessary (if e.g. documentation is failing to build for some reason) this can be skipped by defining
without_haddock
. -
Additionally links to colored html sourcecode are also generated with
hscolour
, which can be disabled by definingwithout_hscolour
.
-
%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 file for package installation time -
%ghc_gen_filelists
: generates rpm filelists. -
%ghc_strip_dynlinked
: strips dynamically linked objects.
%ghc_pkg_recache
: used in %post and %postun for devel subpackage - refreshes the ghc package cache database with .conf file data.
Directories
GHC libraries are installed under %ghcpkgdir/%{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
and ghc-%{pkg_name}-devel.files
.
Compiling non-Cabal packages
Packages compiling Haskell code without Cabal, ie directly with ghc
or ghc --make
, should use -O1
optimization, like Cabal does by default.