From Fedora Project Wiki

No edit summary
(Deprecate this page.)
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{OldGuidelinePage|Haskell}}
= Haskell Packaging Guidelines =
= Haskell Packaging Guidelines =
This documents the guidelines and conventions for packaging Haskell projects in Fedora.
This page documents the guidelines and conventions for packaging [[Haskell]] projects in Fedora.


== What is Haskell? ==
[http://haskell.org/ghc GHC] (Glasgow Haskell Compiler) is the current mainstream Haskell compiler.
''"Haskell is an advanced purely functional programming language. The product of more than twenty years of cutting edge research, it allows rapid development of robust, concise, correct software. With strong support for integration with other languages, built-in concurrency, debuggers, profilers, rich libraries and an active community, Haskell makes it easier to produce flexible, maintainable high-quality software."'' -- (from http://haskell.org/)
Most Haskell packages are released on [http://hackage.haskell.org Hackage] and use the [http://www.haskell.org/cabal/ Cabal] package system.  So the current guidelines mostly focus on packaging for GHC using Cabal.


=== GHC ===
== Spec file templates ==
[http://haskell.org/ghc GHC], the Glasgow Haskell Compiler, is the most popular and widely used Haskell compiler. It complies with Haskell 98, the latest official language specification, and also includes various experimental language ideas. It represents a good picture of what the future of Haskell will look like, so it is a good choice for development.  Most Haskell programs work better or only with GHC.  So currently these guidelines mostly focus on packaging for GHC.  At some later stage if the need arises they may be extended to cover other implementations in more detail.
Spec files in line with these templates are generated automatically by the [https://apps.fedoraproject.org/packages/cabal-rpm cabal-rpm] packaging tool
which also adds dependencies listed in the package's <code>.cabal</code> 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.


Packages should normally be compiled with GHC where possible.  Some Haskell packages might require some other compiler extension not available in GHC but in another compiler implementation in which case that compiler would have to be included in Fedora first before the package can get added to Fedora.  If a package needs special language features they should be mentioned in the review and documented in comments in the spec file.
Standardizing the packaging helps to lower the maintenance burden across Fedora's Haskell packages.


''Rationale: GHC is the best supported compiler in Fedora currently.  Therefore, if something goes wrong, we have a larger skill base to ask for help.''
There are three types of Haskell Cabal packages: library only (Lib), binary only (Bin), and binary and library (BinLib):


=== Cabal ===
=== Library Only ===
''"Cabal is a system for building and packaging Haskell libraries and programs. It defines a common interface for package authors and distributors to easily build their applications in a portable way. Cabal is part of a larger infrastructure for distributing, organizing, and cataloging Haskell libraries and programs.''


''Specifically, the Cabal describes what a Haskell package is, how these packages interact with the language, and what Haskell implementations must do to support packages. The Cabal also specifies some infrastructure (code) that makes it easy for tool authors to build and distribute conforming packages.''
<pre>
%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


''The Cabal is only one contribution to the larger goal. In particular, the Cabal says nothing about more global issues such as how authors decide where in the module name space their library should live; how users can find a package they want; how orphan packages find new owners; and so on."''
BuildRequires:  ghc-Cabal-devel
BuildRequires:  ghc-rpm-macros


(from http://haskell.org/cabal)
%description
@DESCRIPTION@


== Summary and Description ==
%package devel
When packaging things out of [http://hackage.haskell.org Hackage]  or other sources, you may find that the summary or description is incomplete or lacks detail.  Please try to include an appropriate summary and adequate description for Fedora of the library or program in the package so users will know what it does.
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}


== Build and Install ==
%description devel
<code>%build</code> and <code>%install</code> can be done through a series of macros that ensure correctness.
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
</pre>
=== Binary Only ===
<pre>
<pre>
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
%build
%cabal_configure --ghc -p
%ghc_bin_build
%cabal build
 
%cabal haddock
 
%install
%ghc_bin_install
 
 
%files
%license LICENSE
%{_bindir}/%{name}
 
 
%changelog
* @DATE@ Fedora Haskell SIG <haskell@lists.fedoraproject.org>
- spec file generated by cabal-rpm
</pre>
</pre>


<code>%cabal_configure --ghc -p</code> configures the package for building with ghc and profiling.  ''Note: library packages should include profiling libraries where possible or include a justification for not doing so.''  If you omit profiling libraries (the <code>-p</code> option above), anyone wanting to install a profiling version of a dependent library or application will be unable to do so, which is generally considered bad form. There is no need to provide profiling for non-library packages.
=== Library and Binary ===
 
<pre>
%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
 


<code>%cabal build</code> will build a package without installing it.
%build
%ghc_lib_build


<code>%cabal haddock</code> builds HTML Haddock documentation files.


<pre>
%install
%install
rm -rf ${RPM_BUILD_ROOT}
%ghc_lib_install
%cabal_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
</pre>
</pre>


<code>%cabal_install</code> will install the package without including the registration scripts for ghc's library management.  For libraries there are additional macros for generating the install scripts and filelists: see below.
== 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 <code>darcs</code> and <code>xmonad</code>.
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 <code>ghc</code>, are prefixed by "ghc-".  For example the Haskell X11 library package is named <code>ghc-X11</code>, and the Haskell mmap library package is named <code>ghc-mmap</code>, 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 <code>xmonad</code> BinLib package has library subpackages
* <code>ghc-xmonad</code> for the shared library, and
* <code>ghc-xmonad-devel</code> 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 <code>haskell</code>, e.g. <code>haskell-X11</code>.  Such a package would then have subpackages for each compiler and/or interpreter it is built for (e.g. <code>ghc-X11</code>, <code>hugs98-X11</code>, etc).
 
Package naming preserves case to follow the upstream naming conventions as closely as possible.
 
== Headers ==


== Packaging libraries ==
The macro <code>pkg_name</code> is used to carry the name of the upstream library package (i.e. without the Fedora "ghc-" prefix).
=== Naming ===
It should be defined at the top of Lib and BinLib packages:
The names of Haskell library packages should be prefixed with the compiler or interpreter they are intended for.  Package names should follow the upstream naming and preserve case.  For example,  the <code>bzlib</code> library from [http://hackage.haskell.org/ Hackage] packaged for GHC would be named <code>ghc-bzlib</code> in Fedora, and the <code>QuickCheck</code> library would be named <code>ghc-QuickCheck</code>.


If a library is packaged for more than one Haskell compiler or interpreter, the base name should instead be prefixed with <code>haskell</code>, e.g. <code>haskell-X11</code>.  Such a package would then have subpackages for each compiler and/or interpreter it is built for (e.g. <code>ghc-X11</code>, <code>hugs98-X11</code>, etc.
%global pkg_name <package>


''Rationale: The Fedora Project tries to follow upstream as closely as possible. Haskell upstream packages maintain consistent naming schemes across tarball, cabal and ghc package names, and mixed case names are tracked well.''
== Cabal Flags ==
Cabal flags for build options should be set by changing the package's <code>.cabal</code> file: this can be done with the <code>cabal-tweak-flag</code> script to avoid having to carry and maintain patches for this.
<code>%cabal_configure_options</code> can be set to pass other options to Cabal.


=== Static vs. Dynamic Linking ===
Modifying the <code>.cabal</code> file flags defaults allows packagers and tools like <code>cabal-rpm</code> to track actual package dependencies correctly.
Current releases of GHC do not yet support generating shared libraries, so all ghc libraries are static and library packages of them should provide themselves as a -devel package also to allow migrating parts of them to -devel subpackages in the future when shared libraries become the norm:


<pre>
== Dependency Generation ==
Provides: ghc-%{pkg_name}-devel = %{version}-%{release}
Spec file build dependencies are generated by the <code>cabal-rpm</code> packaging tool.
</pre>
 
RPM dependencies for Haskell libraries are automatically generated at build-time by the <code>ghc-deps.sh</code> script.


Static linking means that when updating any library, all packages that depend on it will also need to be rebuilt before they see any changes, and in the event of a security advisory, all of them need to be rebuilt also.
The <code>cabal-tweak-dep-ver</code> script can be used to bump versions of dependencies in the package .cabal file.


This is not true for linking to other languages using the Foreign Function Interface (FFI)When linking to these libraries, the standard dynamic linker is used.
== Shared and static library linking ==
GHC uses static libraries by default, but supports shared libraries on some architectures: currently i686 and x86_64Lib 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.


''Note: the situation is similar to OCaml, and the usual rules that apply there apply here as well.''
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.


Keep in mind though, that some special packages may still do code generation at runtime in which case they may need Requires as well as BuildRequires for their dependencies: examples include xmonad and yi which may require certain libraries to be present to work.
Executables in Bin and BinLib packages should be dynamically linked to shared libraries.


=== Package directory ===
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 <code>%ghc_fix_dynamic_rpath</code> to fix its RPATH.
GHC libraries should be installed under <code>%pkg_libdir</code> as done by Cabal.


<pre>
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.
%global pkg_libdir %{_libdir}/ghc-%{ghc_version}/%{pkg_name}-%{version}
</pre>


=== File lists ===
== RPM Macros ==
You can generate filelists for libraries and profiling library subpackages using the following macro, rather than doing it by hand:
The templates all have buildrequires for ghc-rpm-macros, which provides [http://pkgs.fedoraproject.org/cgit/ghc-rpm-macros.git/tree/ghc-rpm-macros.ghc macros.ghc] to assist with packaging Haskell Cabal packages.


<pre>
<pre>
%ghc_gen_filelists %{name}
BuildRequires:  ghc-rpm-macros
</pre>
</pre>


This macro takes one parameter, which is just a name prefix to be used for the file lists.  This same parameter must be used later in the files section.
The main commonly used macros are:


The files section would then look something like this:
* %ghc_bin_build
* %ghc_lib_build
* %ghc_bin_install
* %ghc_lib_install


<pre>
They are used in the templates and explained in more detail below.
%files -f %{name}.files
%doc LICENSE README
%{pkg_docdir}


%files -n %{name}-prof -f %{name}-prof.files
== Bin packages ==
</pre>


=== Install scripts ===
Bin package executables should be dynamically linked to shared Haskell libraries when available, but this can be overridden if necessary by defining the <code>ghc_without_dynamic</code> macro.
Libraries must be registered with the installed ghc package.


To generate registration scripts that can be embedded in the package first include the following in %build:
<pre>
<pre>
%ghc_gen_scripts
%build
</pre>
%ghc_bin_build
and then in %install install them with:
<pre>
%ghc_install_scripts
</pre>


Finally the actual registering of packages must be done at install and uninstall time with the following scriplets:
<pre>
%post -n ghc-%{pkg_name}
%ghc_register_pkg


%preun -n ghc-%{pkg_name}
%install
if [ "$1" -eq 0 ] ; then
%ghc_bin_install
  %ghc_unregister_pkg
fi
</pre>
</pre>


=== Documentation ===
<code>%ghc_bin_build</code> is used to configure and build bin packages. It runs:
Normal doc files for a package should live in the usual place.  Haskell supports inline API docs using the <code>haddock</code> tool (bundled in the <code>ghc</code> package as of 6.10), for which the situation is somewhat different. The master directory for Haddock files is <code>%{_docdir}/ghc/libraries</code>, with one directory per package under there.  The <code>index.html</code> file for this directory should be regenerated every time a package is installed, upgraded, or removed.  Since <code>%{_docdir}/ghc/libraries</code> is owned by <code>ghc-doc</code> it is recommended to subpackage haddock documentation in a <code>doc</code> subpackage, which can require <code>ghc-doc</code>.
* <code>%global debug_package %{nil}</code>: debuginfo is disabled since ghc's output is not in GDB format.
* <code>%cabal_configure</code>: configure the package for building and dynamic linking.
* <code>%cabal build</code>: builds the package.


If a package comes with meaningful Haddock documentation, your spec file should define
<code>%ghc_bin_install</code> is used to install bin packages.  It runs:
* <code>%cabal_install</code>: installs the package.
* <code>%ghc_strip_dynlinked</code>: strips the dynamically linked binary.


<pre>%global pkg_docdir %{_docdir}/ghc/libraries/%{pkg_name}</pre>
== Lib and BinLib packages ==


and the <code>%build</code> section should contain the following:
BinLib package executables should be dynamically linked to other shared Haskell libraries when available, but this can be overridden if necessary by defining the <code>ghc_without_dynamic</code> macro.


<pre>%cabal haddock</pre>
Devel subpackages need to setup some Requires:


This will cause the HTML version of the Haddock documentation to be generated.  If built, it will automatically be installed to the correct location by <code>%cabal_install</code> without any further intervention.
<pre>
%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}
</pre>


To automatically update the master index of all Haddock documentation in <code>/usr/share/doc/ghc/libraries</code>, add the following to your <code>%post</code> and <code>%postun</code> scriptlets:
Lib packages need to use <code>%setup -n</code>:


<pre>
<pre>
%post
%prep
%ghc_reindex_haddock
%setup -q -n %{pkg_name}-%{version}
 
%postun
if [ "$1" -eq 0 ] ; then
  %ghc_reindex_haddock
fi
</pre>
</pre>


The ghc haddock docs index will then be updated after installation, update, or removal of the package.
Both Lib and BinLib have:


Finally, you'll want to add the following to your <code>%files</code> section, so that the Haddock docs will be picked up correctly.
<pre>
%build
%ghc_lib_build


<pre>%{pkg_docdir}</pre>


== Packaging programs ==
%install
=== Naming ===
%ghc_lib_install
For packages of Haskell programs the usual Fedora Package Naming Guidelines must be followed: ie in they should follow the upstream name. Examples include projects like <code>darcs</code>, <code>haddock</code>, and <code>xmonad</code>.  If the package also generates libraries, then the libraries SHOULD be subpackaged as a Haskell library package named after the compiler or interpreter as above.


Any libraries provided should go into a separate subpackage: eg the spec file for xmonad would generate three rpm packages: <code>xmonad</code>, <code>ghc-xmonad</code>, and <code>ghc-xmonad-prof</code>.  xmonad would require <code>ghc-xmonad</code>, but not visa versa.  <code>ghc-xmonad</code> would contain a line in its description explaining that these are the libraries necessary for <code>xmonad</code> to run.


''Rationale: Program packages should be easy to find by their upstream name. Binaries are recognized on their name alone.  Furthermore, they generally do not require a compiler to run.  Therefore the name provided should simply be the upstream name.
%post devel
%ghc_pkg_recache




%postun devel
%ghc_pkg_recache
</pre>


== Debug Information ==
<code>%ghc_lib_build</code> is used to configure, build and generate documentation for Lib and BinLib packages. It runs:
Debuginfo packages should not be built for GHC binaries, since they will be empty anyway.
* <code>%global debug_package %{nil}</code>: debuginfo is disabled since ghc's output is not in DWARF format.
 
* <code>%cabal_configure --ghc -p</code>: configures the package for building with ghc and profiling.  Libraries should build profiling versions of their static libraries.
<pre>
* <code>%cabal build</code>: builds the package.
%global debug_package %{nil}
* <code>%cabal haddock</code>: generates HTML library documentation from the source code.
</pre>
** If necessary (if e.g. documentation is failing to build for some reason) this can be skipped by defining <code>without_haddock</code>.
** Additionally links to colored html sourcecode are also generated with <code>hscolour</code>, which can be disabled by defining <code>without_hscolour</code>.


''Rationale: GHC does not emit DWARF debug data.''
<code>%ghc_lib_install</code> is used to install Lib and BinLib packages.  It runs:
* <code>%cabal_install</code>: installs the package without registering it in ghc-pkg.
* <code>%cabal_pkg_conf</code>: creates ghc-pkg .conf metadata file for package installation time
* <code>%ghc_gen_filelists</code>: generates rpm filelists.
* <code>%ghc_strip_dynlinked</code>: strips dynamically linked objects.


== Macros ==
<code>%ghc_pkg_recache</code>: used in %post and %postun for devel subpackage - refreshes the ghc package cache database with .conf file data.
A number of macros are defined for convenince for packaging cabal packages and libraries for ghc. Similar macros could also be defined for other compilers.  It would be good to follow this scheme as far as possible also when implementing macros for other Haskell compilers or interpreters to keep portability.


* %cabal
== Directories ==
* %cabal_configure
GHC libraries are installed under <code>%ghcpkgdir/%{pkg_name}-%{version}</code>:
* %cabal_makefile
* %ghc_gen_scripts
* %cabal_install
* %ghc_install_scripts
* %ghc_gen_filelists()
* %ghc_register_pkg
* %ghc_unregister_pkg
* %ghc_reindex_haddock


You can find the current [http://cvs.fedoraproject.org/viewvc/devel/ghc/ghc-rpm-macros.ghc?view=co <code>ghc.macros</code>] definitions in the ghc package.
Library documentation lives under <code>%ghclibdocdir/%{pkg_name}-%{version}</code>.


== Spec Templates ==
== File lists ==
There are three types of packages: Library only, Library and Binary, and Binary only. Templates are provided for all three cases since they are slightly different:
Filelists for shared and devel library subpackages are generated through <code>%ghc_lib_install</code> using the macro <code>%ghc_gen_filelists</code>.


* [http://git.fedorahosted.org/git/cabal2spec.git?p=cabal2spec.git;a=blob_plain;f=spectemplate-ghc-lib.spec;hb=HEAD Library Only Template]
It generates the filelists <code>ghc-%{pkg_name}.files</code> and <code>ghc-%{pkg_name}-devel.files</code>.
* [http://git.fedorahosted.org/git/cabal2spec.git?p=cabal2spec.git;a=blob_plain;f=spectemplate-ghc-bin.spec;hb=HEAD Binary Only Template]
* [http://git.fedorahosted.org/git/cabal2spec.git?p=cabal2spec.git;a=blob_plain;f=spectemplate-ghc-binlib.spec;hb=HEAD Library and Binary Template].


<code>cabal2spec</code> provides a simple script which can generate .spec files using these templates directly out of a Cabal package or .cabal file for any of the three cases.  The .spec files should build for most general Cabal hackage packages with minimal changes: for example you might need to specify BuildRequires for other build dependencies and possibly Requires for any runtime or linking dependencies.  Please report any problems in [https://bugzilla.redhat.com/enter_bug.cgi?product=Fedora&component=cabal2spec bugzilla (in the cabal2spec component of the Fedora product)].
== Compiling non-Cabal packages ==
Packages compiling Haskell code without Cabal, ie directly with <code>ghc</code> or <code>ghc --make</code>, should use <code>-O1</code> optimization, like Cabal does by default.


== References ==
== References ==
* http://petersen.fedorapeople.org/cabal2spec
* http://fedorahosted.org/cabal2spec
* http://urchin.earth.li/~ian/haskell-policy/ - Debian Haskell packaging policy
* http://pkgs.fedoraproject.org/gitweb/?p=ghc-rpm-macros.git
* http://pkg-haskell.alioth.debian.org/haskell-policy/ - Debian Haskell packaging policy
* [[Packaging/OCaml|Fedora OCaml Packaging Guidelines]]
* [[Packaging/OCaml|Fedora OCaml Packaging Guidelines]]
* [[SIGs/Haskell|Fedora Haskell SIG]]
* [[SIGs/Haskell|Fedora Haskell SIG]]
[[Category:Packaging guidelines]]

Latest revision as of 20:06, 21 December 2018

Warning.png
This is an old copy of a packaging guideline, preserved here in the wiki while we complete the transition to the Fedora documentation system. The current version is located at https://docs.fedoraproject.org/en-US/packaging-guidelines/Haskell/. Please update your bookmarks.

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 <package>

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 defining without_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.

References