From Fedora Project Wiki

< PackagingDrafts

Revision as of 05:29, 26 November 2008 by Petersen (talk | contribs) (drop mention cabal-rpm for now until it generates compliant spec files and is included in fedora and move static linking to library section)

Haskell Packaging Guidelines

This documents the guidelines and conventions for packaging Haskell projects in Fedora.

What is Haskell?

(from http://haskell.org/)

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.

GHC

GHC, or 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 numerous 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. Many 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.

Base package naming

Libraries

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 bzlib library from Hackage packaged for GHC would be named ghc-bzlib in Fedora, and the QuickCheck library would be named ghc-QuickCheck.

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, hug98-X11, etc.

Rationale: The Fedora Project tries to follow upstream as closely as possible. Upstream maintains very consistent naming schemes, and mixed case names are tracked very well.

Programs

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 darcs, haddock, and xmonad. 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.

Rationale: Program packages should be easy to find by their upstream name.

Description

When packaging things out of Hackage or other sources, you may find that the description is incomplete or improperly labeled. Please double check all parts of the package description so that it meets Fedora's standards for writing quality.

Build and Install

%build and %install can be done through a series of macros that ensure correctness.

%build
%cabal_configure -p --ghc
%cabal build
%cabal haddock

Note: for library packages please include profiling libraries where possible or include a justification for not doing so. If you omit profiling libraries (the -p option above), anyone wanting to install a profiling version of a dependent library or application will be unable to do so. This is considered bad form.

%cabal build will build a package without installing it.

%cabal haddock builds HTML Haddock documentation files.

%install
rm -rf ${RPM_BUILD_ROOT}
%cabal_install
%ghc_install_scripts
%ghc_gen_filelists %{name}

%cabal_install will install the package without including the registration scripts for ghc's library management. %ghc_install_scripts generates and installs those scripts. %ghc_gen_filelists generates the list of files in the package.

Packaging libraries

Static vs. Dynamic Linking

Currently GHC does not have good support for shared libraries yet so all libraries are static and library packages with them should provide performs only static linking with other Haskell libraries, partly due to a significant amount of optimizations done when inlining functions from other libraries. Therefore, when recompiling any library, all packages that depend on it will also need to be recompiled, and in the event of a security advisory, one needs to be applied to all dependencies.

This is not true for libraries linked through other languages using the Foreign Function Interface (FFI). When linking to these libraries, the standard dynamic linker is used.

Note: this is very similar to OCaml, and the usual rules that apply there apply here as well.

Keep in mind though, that some special packages may still do code generation at runtime in which case you 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.

Package directory

GHC libraries should be installed under libdir/ghc as done by Cabal using the %pkg_libdir macro.

%define pkg_libdir %{_libdir}/ghc-%{ghc_version}/%{pkg_name}-%{version}

File lists

You can generate filelists for libraries and profiling library subpackages using the following macro, rather than doing it by hand:

%ghc_gen_filelists %{name}

This macro takes one parameter, which is just a name to be used for the file lists. This same parameter must be used later in the files section.

The files section would then look something like this:

%files -f %{name}.files
%defattr(-,root,root,-)
%doc LICENSE README
%{pkg_docdir}

%files -n %{name}-prof -f %{name}-prof.files
%defattr(-,root,root,-)

Install scripts

Libraries must be registered with the installed GHC.

To generate registration scripts that can be embedded in the package, include the following in %build, and include the following install script macros.

%ghc_gen_scripts

To separate the copying phase from the registration phase of installation, include the following in %install

%ghc_install_scripts

To register packages at install time, make sure to include the following bits:

%post -n ghc-%{pkg_name}
%ghc_postinst_script


%preun -n ghc-%{pkg_name}
%ghc_preun_script

Packaging programs

Programs are packaged in their simple name, eg xmonad would be named xmonad. Any libraries should go into a separate subpackage: eg the spec file for xmonad would generate three rpm packages: xmonad, ghc-xmonad, and ghc-xmonad-prof. xmonad would require ghc-xmonad, but not visa versa. ghc-xmonad would contain a line in its description explaining that these are the libraries necessary for xmonad to run.

Binary packages should be normally be compiled with GHC when possible. Some Haskell packages might require some compiler extension not provided in GHC. Alternate compilers may be used so long as they are packaged for Fedora. Please make it clear what feature is needed when submitting that package for review, and leave an appropriate comment in the .spec file.

If a compiler is not available in Fedora, it can be submitted for package review as well. You can block your review request on the compiler review request, and once it passes review, your package can then be reviewed and get accepted too. Please note that your compiler must follow Fedora's guidelines for packaging and package submission.

Rationale: Binaries are recognized on their name alone. Furthermore, they do not require a compiler to run. Therefore the name provided should simply be the upstream name. GHC is the best supported compiler in Fedora currently. Therefore, if something goes wrong, we have a larger skill base to ask for help.

Documentation

Normal docs for a package should live in the usual place. Haskell supports inline API docs using the haddock tool (bundled in the ghc package as of 6.10), for which the situation is somewhat different. The master directory for Haddock files is %{_docdir}/ghc/libraries, with one directory per package under there. The index.html file for this directory should be regenerated every time a package is installed, upgraded, or removed.

If a package comes with meaningful Haddock documentation, your spec file should define

%define pkg_docdir %{_docdir}/ghc/libraries/%{pkg_name}

and the %build section should contain the following:

%cabal haddock

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 %cabal_install without any further intervention.

To automatically update the master index of all Haddock documentation in /usr/share/doc/ghc/libraries, add the following to both your %post and %postun scriptlets:

%ghc_reindex_haddock

The docs will be added after installation, fixed after an upgrade, and removed after uninstallation.

Finally, you'll want to add the following to your %files section, so that the Haddock docs will be picked up correctly.

%{pkg_docdir}

Debug Information

Debuginfo packages should not be built for GHC binaries, since they will be empty anyway.

Rationale: GHC does not emit DWARF debug data.

Macros

A number of macros are defined for cabal packages and ghc library packaging. They have names like %cabal_build and %cabal_install. Similar macros can be defined for other compilers. Please stick to this scheme when implementing macros for other Haskell compilers or interpreters.

  • %cabal
  • %cabal_configure
  • %cabal_build
  • %cabal_makefile
  • %cabal_haddock
  • %cabal_install
  • %ghc_install_scripts
  • %ghc_gen_filelists()
  • %ghc_postinst_script
  • %ghc_preun_script
  • %ghc_reindex_haddock

You can find the current ghc.macros in the ghc package.

Spec Templates

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:

There is a simple script cabal2spec included in the latest ghc package 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 runtime any dependencies. Please report any problems in Bugzilla against the ghc component of the Fedora product.

References