openSUSE:Packaging Haskell
Build Service Tutorial 路 Tips & Tricks 路 Cross Distribution Howto 路 Packaging checks
Desktop menu categories 路 RPM Macros 路 Scriptlets 路 Init scripts 路 How to write good changes
Packaging Haskell for openSUSE
Most Haskell sources are published at Hackage [[1]] using a build and install tool named Cabal. The Cabal tool is used to create openSUSE RPM packages from Hackage sources. A small set of RPM macros is provided in package ghc-rpm-macros.
cabal2spec: Automatic spec file generation
The fastest route to Haskell packaging is through cabal2spec obtained from OBS in devel:languages:haskell, Tumbleweed from official repositories or via cabal:
cabal install cabal2spec
To generate a spec file, simply run
cabal2spec your-awesome-project.cabal
and it will create a spec file of the same name but with the '.spec' prefix.
Potential Problems
Firstly, the spec file generated by cabal2spec will grab pristine source from hackage based on the package name(s). If your project isn't on hackage, then either upload it or upload the source to OBS with your spec file.
Next, if you make no changes to the spec file and want OBS to grab the source from hackage, there is a change that the package has had its metadata altered. Metadata revisions are when a hackage package maintainer changes small features on spec files (for example relaxing an upper bound on a dependency) to allow a package to build without having to rey-load source code. In this case, the revised source can only be retrieved using cabal, which downloads the source and patches it. OBS doesn't do this! You must manually patch the cabal file in the source to keep the package up to date with revisions.
Finally, if you plan on allowing source to be fetched, you must enable a source service in the package. This is as simple as creating a file named _service and filling it with the following:
<services> <service name="download_files" /> </services>
You can (and should) read more about source services here and here
Package types and package naming
Haskell's cabal packages come in three flavors: Bin, Lib, and BinLib.
Programs (Bin packages)
For programs use the upstream package name if it does not conflict with another openSUSE package.
Libraries (Lib packages)
A library package name is obtained by prefixing the upstream name with ghc-. The library package contains the shared library. The corresponding development package name is the library package name with suffix -devel and contains precompiled headers, documentation, and profiling and static libraries. The latter are required by ghci. Upstream plans are to support dynamic linking in ghci in release 7.8.1 of ghc.
Programs with library (BinLib packages)
A cabal package that contains both a program and a library is packaged as a BinLib package. The spec file must specify packaging for both the program (Bin) and the library (Lib).
Dependencies
Build dependencies (BuildRequires)
All Haskell packages must require ghc-rpm-macros and ghc-Cabal-devel for build. A Haskell package should not require hscolour (sic!) for build as this requirement is controlled by ghc-rpm-macros. Currently we need to turn off hscolour during bootstrap and this is the easiest way to do that for all packages.
Require Haskell libraries by ghc-<library-name>-devel without version number constraints to keep maintenance overhead low. Libraries ghc and prim are included in ghc-compiler and hence must not be required for build.
Library dependencies (Requires)
Haskell and other dependencies will be generated automatically.
Devel packages dependencies
Dependencies for Haskell devel packages will be generated automatically. Other libraries must be added in Requires tags. In addition every devel packages needs the following:
Requires: ghc-compiler Requires(post): ghc-compiler Requires(postun): ghc-compiler Requires: %{name} = %{version}-%{release}
Configuring and building
To configure and build the sources use the %ghc_bin_build macro for Bin packages and %ghc_lib_build for Lib and BinLib packages. This will configure the package with all defaults and build it.
Overriding package defaults
To override packages defaults define a macro cabal_configure_options. These options will be passed to the cabal configure command. Or use cabal-tweak-flag command from ghc-rpm-macros. Example:
%define cabal_configure_options -f"utf8"
or the same:
cabal-tweak-flag utf8 True
For change cabal dependencies version use cabal-tweak-dep-ver command from ghc-rpm-macros. Example from xmonad.spec:
%prep %setup -q cabal-tweak-dep-ver utf8-string '< 0.4' '< 1.1'
Installing
In most cases %ghc_bin_install resp. %ghc_lib_install does the job. Sometimes manual pages and other documentation is not installed by the underlying cabal and needs to be installed manually.
Fixing broken RPATHs
If a program links to a Haskell library provided by the same package cabal sets an RPATH to the build directory rather than the install directory. The RPATH needs to be fixed by a call to %ghc_fix_dynamic_rpath followed by all affected programs. If you forget one rpmlint will complain about it and let the build fail.
Extra macros for complex packages (compiler hackers only)
- %ghc_lib_subpackage macro generates tags for ghc-<name> and corresponding devel package
- %ghc_suse_disable_debug_packages disables debug and debuginfo packages the openSUSE way
- %ghc_gen_filelist creates a filelist files for ghc-<name> and corresponding devel package
- %ghc_strip_dynlinked strip programs and shared objects
Examples
Program
# # spec file for package cabal-install # # Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via http://bugs.opensuse.org/ # Name: cabal-install Version: 1.16.0.2 Release: 0 Summary: Command-line program to manage Haskell software License: BSD-3-Clause Group: Development/Languages/Other BuildRoot: %{_tmppath}/%{name}-%{version}-build Url: http://hackage.haskell.org/package/%{name} Source0: http://hackage.haskell.org/packages/archive/%{name}/%{version}/%{name}-%{version}.tar.gz ExclusiveArch: %{ix86} x86_64 %{ghc_arches} BuildRequires: ghc-Cabal-devel BuildRequires: ghc-HTTP-devel BuildRequires: ghc-array-devel BuildRequires: ghc-bytestring-devel BuildRequires: ghc-containers-devel BuildRequires: ghc-directory-devel BuildRequires: ghc-filepath-devel BuildRequires: ghc-mtl-devel BuildRequires: ghc-network-devel BuildRequires: ghc-old-time-devel BuildRequires: ghc-pretty-devel BuildRequires: ghc-process-devel BuildRequires: ghc-random-devel BuildRequires: ghc-rpm-macros BuildRequires: ghc-time-devel BuildRequires: ghc-unix-devel BuildRequires: ghc-zlib-devel %description Command-line program to manage Haskell software by automating the fetching, configuration, compilation, and installation of Haskell libraries and programs %prep %setup -q %build %ghc_bin_build %install %ghc_bin_install %files %doc LICENSE README %attr(755,root,root) %{_bindir}/cabal %changelog
Library
# # spec file for package ghc-utf8-string # # Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via http://bugs.opensuse.org/ # %global pkg_name utf8-string Name: ghc-utf8-string Version: 0.3.7 Release: 0 Summary: Support for reading and writing UTF8 Strings License: BSD-3-Clause Group: System/Libraries Url: http://hackage.haskell.org/package/%{pkg_name} Source0: http://hackage.haskell.org/packages/archive/%{pkg_name}/%{version}/%{pkg_name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: ghc-Cabal-devel BuildRequires: ghc-rpm-macros %description A UTF8 layer for IO and Strings. The utf8-string package provides operations for encoding UTF8 strings to Word8 lists and back, and for reading and writing UTF8 without truncation. %package devel Summary: Haskell %{pkg_name} library development files Group: Development/Libraries/Other Requires: ghc-compiler Requires(post): ghc-compiler Requires(postun): ghc-compiler Requires: %{name} = %{version}-%{release} %description devel A UTF8 layer for IO and Strings. The utf8-string package provides operations for encoding UTF8 strings to Word8 lists and back, and for reading and writing UTF8 without truncation. %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 %doc LICENSE %files devel -f %{name}-devel.files %changelog
Program and library
# # spec file for package pandoc # # Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via http://bugs.opensuse.org/ # %global pkg_name pandoc Name: pandoc Version: 1.11.1 Release: 0 Summary: Conversion between markup formats License: GPL-2.0 Group: Development/Languages/Other Url: http://hackage.haskell.org/package/%{name} Source0: http://hackage.haskell.org/packages/archive/%{name}/%{version}/%{name}-%{version}.tar.gz BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRequires: ghc-Cabal-devel BuildRequires: ghc-rpm-macros # Begin cabal-rpm deps: BuildRequires: ghc-HTTP-devel BuildRequires: ghc-base64-bytestring-devel BuildRequires: ghc-blaze-html-devel BuildRequires: ghc-blaze-markup-devel BuildRequires: ghc-bytestring-devel BuildRequires: ghc-citeproc-hs-devel BuildRequires: ghc-containers-devel BuildRequires: ghc-data-default-devel BuildRequires: ghc-directory-devel BuildRequires: ghc-extensible-exceptions-devel BuildRequires: ghc-filepath-devel BuildRequires: ghc-highlighting-kate-devel BuildRequires: ghc-json-devel BuildRequires: ghc-mtl-devel BuildRequires: ghc-network-devel BuildRequires: ghc-old-locale-devel BuildRequires: ghc-old-time-devel BuildRequires: ghc-pandoc-types-devel BuildRequires: ghc-parsec-devel BuildRequires: ghc-process-devel BuildRequires: ghc-random-devel BuildRequires: ghc-syb-devel BuildRequires: ghc-tagsoup-devel BuildRequires: ghc-temporary-devel BuildRequires: ghc-texmath-devel BuildRequires: ghc-text-devel BuildRequires: ghc-time-devel BuildRequires: ghc-xml-devel BuildRequires: ghc-zip-archive-devel BuildRequires: ghc-zlib-devel # End cabal-rpm deps BuildRequires: chrpath %description Pandoc is a Haskell library for converting from one markup format to another, and a command-line tool that uses this library. It can read markdown and (subsets of) HTML, reStructuredText, LaTeX, DocBook, MediaWiki markup, and Textile, and it can write markdown, reStructuredText, HTML, LaTeX, ConTeXt, Docbook, OpenDocument, ODT, Word docx, RTF, MediaWiki, Textile, groff man pages, plain text, Emacs Org-Mode, AsciiDoc, EPUB (v2 and v3), FictionBook2, and S5, Slidy and Slideous HTML slide shows. Pandoc extends standard markdown syntax with footnotes, embedded LaTeX, definition lists, tables, and other features. A compatibility mode is provided for those who need a drop-in replacement for Markdown.pl. In contrast to existing tools for converting markdown to HTML, which use regex substitutions, pandoc has a modular design: it consists of a set of readers, which parse text in a given format and produce a native representation of the document, and a set of writers, which convert this native representation into a target format. Thus, adding an input or output format requires only adding a reader or writer. %package -n ghc-%{name} Summary: Haskell %{name} library Group: System/Libraries %description -n ghc-%{name} Pandoc is a Haskell library for converting from one markup format to another, and a command-line tool that uses this library. It can read markdown and (subsets of) HTML, reStructuredText, LaTeX, DocBook, MediaWiki markup, and Textile, and it can write markdown, reStructuredText, HTML, LaTeX, ConTeXt, Docbook, OpenDocument, ODT, Word docx, RTF, MediaWiki, Textile, groff man pages, plain text, Emacs Org-Mode, AsciiDoc, EPUB (v2 and v3), FictionBook2, and S5, Slidy and Slideous HTML slide shows. Pandoc extends standard markdown syntax with footnotes, embedded LaTeX, definition lists, tables, and other features. A compatibility mode is provided for those who need a drop-in replacement for Markdown.pl. In contrast to existing tools for converting markdown to HTML, which use regex substitutions, pandoc has a modular design: it consists of a set of readers, which parse text in a given format and produce a native representation of the document, and a set of writers, which convert this native representation into a target format. Thus, adding an input or output format requires only adding a reader or writer. %package -n ghc-%{name}-devel Summary: Haskell %{name} library development files Group: Development/Languages/Other Requires: ghc-compiler Requires(post): ghc-compiler Requires(postun): ghc-compiler Requires: %{name} = %{version}-%{release} %description -n ghc-%{name}-devel Pandoc is a Haskell library for converting from one markup format to another, and a command-line tool that uses this library. It can read markdown and (subsets of) HTML, reStructuredText, LaTeX, DocBook, MediaWiki markup, and Textile, and it can write markdown, reStructuredText, HTML, LaTeX, ConTeXt, Docbook, OpenDocument, ODT, Word docx, RTF, MediaWiki, Textile, groff man pages, plain text, Emacs Org-Mode, AsciiDoc, EPUB (v2 and v3), FictionBook2, and S5, Slidy and Slideous HTML slide shows. Pandoc extends standard markdown syntax with footnotes, embedded LaTeX, definition lists, tables, and other features. A compatibility mode is provided for those who need a drop-in replacement for Markdown.pl. In contrast to existing tools for converting markdown to HTML, which use regex substitutions, pandoc has a modular design: it consists of a set of readers, which parse text in a given format and produce a native representation of the document, and a set of writers, which convert this native representation into a target format. Thus, adding an input or output format requires only adding a reader or writer. %prep %setup -q %build %ghc_lib_build %install %ghc_lib_install %ghc_fix_dynamic_rpath pandoc %post -n ghc-%{name}-devel %ghc_pkg_recache %postun -n ghc-%{name}-devel %ghc_pkg_recache %files %doc COPYING %doc README %{_bindir}/%{name} %{_datadir}/%{name}-%{version} %{_mandir}/man1/pandoc.1* %{_mandir}/man5/pandoc_markdown.5* %files -n ghc-%{name} -f ghc-%{name}.files %doc COPYING %files -n ghc-%{name}-devel -f ghc-%{name}-devel.files %doc README %changelog