Haskell package guidelines

From ArchWiki
Revision as of 10:23, 14 June 2008 by Gwern (Talk | contribs) (Libraries: sp)

Jump to: navigation, search

Haskell on Arch Linux

Goals:

  • all hackage packages into AUR or community.
  • automatic conversion of new cabal packages to AUR packages
  • make Arch Linux the most up to date Haskell platform around

Community

#arch-haskell on freenode.

Guidelines

We're working on a tool to automate PKGBUILD generation. Latest version of cabal2arch is here,

Development version:

Or:

  • cabal install cabal2arch

This will automate the entire process, allowing us to import the 500+ libraries on hackage, and keep them up to date.

Creating new packages with cabal2arch

This example illustrates how to create a new package with cabal2arch. We'll make a new package for the delimited continuations library, CC-delcont:

First, find the hackage page for CC-delcont, then identify the link to the .cabal file. Use this link as an argument to cabal2arch:

$ cd /tmp
$ cabal2arch http://hackage.haskell.org/packages/archive/CC-delcont/0.2/CC-delcont.cabal
Using /tmp/tmp.Ig0H8jCOyO/CC-delcont.cabal
Fetching http://hackage.haskell.org/packages/archive/CC-delcont/0.2/CC-delcont-0.2.tar.gz
Created /tmp/haskell-cc-delcont.tar.gz

Checking what was created:

$ ls
haskell-cc-delcont  haskell-cc-delcont.tar.gz

You can now inspect the PKGBUILD and install script for the library:

   # Contributor: Don Stewart <dons@galois.com>
   # Package generated by cabal2arch 0.2.1.1
   pkgname=haskell-cc-delcont
   pkgrel=1
   pkgver=0.2
   pkgdesc="Delimited continuations and dynamically scoped variables"
   url="http://code.haskell.org/~dolio/CC-delcont"
   license=('custom:OtherLicense')
   arch=('i686' 'x86_64')
   makedepends=('ghc')
   source=(http://hackage.haskell.org/packages/archive/CC-delcont/0.2/CC-delcont-0.2.tar.gz)
   install=haskell-cc-delcont.install
   md5sums=('e52149fca9bf76330a7c159917152790')
   build() {
       cd $startdir/src/CC-delcont-0.2
       runhaskell Setup configure --prefix=/usr || return 1
       runhaskell Setup build                   || return 1
       runhaskell Setup register   --gen-script || return 1
       runhaskell Setup unregister --gen-script || return 1
       install -D -m744 register.sh   $startdir/pkg/usr/share/haskell/$pkgname/register.sh
       install    -m744 unregister.sh $startdir/pkg/usr/share/haskell/$pkgname/unregister.sh
       runhaskell Setup copy --destdir=$startdir/pkg || return 1
       install -D -m644 LICENSE $startdir/pkg/usr/share/licenses/$pkgname/LICENSE || return 1
   }

It follows the conventions for Haskell packages:

  • libraries are prefixed with "haskell-"
  • core libraries are not included as explicit dependencies, since ghc provides them
  • since haskell libraries are statically linked, the package only has makedepends requirements
  • it uses cabal to generate a post-install register/unregister script, with a standard name

All Haskell libraries should follow these naming conventions, and using the cabal2arch tool will ensure this is the case.

Inspect the bundle, and confirm you can build and install it:

   $ makepkg -s
   $ makepkg -i

And we're ready to go. Now your .tar.gz is ready to upload to AUR.

Libraries

In general, each .cabal file should map to one PKGBUILD. The following conventions hold:

  • libraries have their cabal names prefixed with "haskell-"
  • all haskell dependencies are statically linked, so can go in the makedepends field.
  • all libraries have a dependency on 'ghc'
  • libraries don't need to have explicit dependencies on core Haskell packages -- these come in the 'ghc' package. (e.g. array, base, containers, random, process etc).
  • we want to resolve dependencies with a fixed constraint to base>=3.0
  • be careful about dependencies on the libraries provided by the basic 'ghc' package, which include:
ALUT-2.1.0.0        cgi-3001.1.5.1       network-2.1.0.0       regex-base-0.72.0.1
Cabal-1.2.3.0       containers-0.1.0.1   old-locale-1.0.0.0    regex-compat-0.71.0.1
GLUT-2.1.1.1        directory-1.0.0.0    old-time-1.0.0.0      regex-posix-0.72.0.2
HUnit-1.2.0.0       fgl-5.4.1.1          packedstring-0.1.0.0  stm-2.1.1.0
OpenAL-1.3.1.1      filepath-1.1.0.0     parallel-1.0.0.0      template-haskell-2.2.0.0
OpenGL-2.2.1.1      haskell-src-1.0.1.1  parsec-2.1.0.0        time-1.1.2.0
QuickCheck-1.1.0.0  haskell98-1.0.1.0    pretty-1.0.0.0        unix-2.3.0.0
array-0.1.0.0       hpc-0.5.0.0          process-1.0.0.0       xhtml-3000.0.2.1
base-3.0.1.0        html-1.0.1.1         random-1.0.0.0
bytestring-0.9.0.1  mtl-1.1.0.0          readline-1.0.1.0

These libraries don't need explicit dependencies to be set.

Registering Haskell libraries is done via a register hook:


build() {
   cd $startdir/src/cabal2arch-0.1
   runhaskell Setup configure --prefix=/usr || return 1
   runhaskell Setup build                   || return 1
   -- generate register scripts
   runhaskell Setup register   --gen-script || return 1
   runhaskell Setup unregister --gen-script || return 1
   install -D -m744 register.sh    $startdir/pkg/usr/share/haskell/$pkgname/register.sh
   install    -m744 unregister.sh $startdir/pkg/usr/share/haskell/$pkgname/unregister.sh
   runhaskell Setup copy --destdir=$startdir/pkg || return 1
   -- usual Haskell BSD3 license isnt' official
   install -D -m644 LICENSE $startdir/pkg/usr/share/licenses/$pkgname/LICENSE || return 1
}


  • Examples:
haskell-zlib, haskell-mersenne-random

Executables

  • Have their normal name. Examples:
hmp3, xmonad, ghc, cabal-install

Building all of Hackage

The following simple script, with cabal-install and cabal2arch installed, will do a simple run over all the Haskell packages on haskell.org, creating arch packages for them:


   #!/bin/sh
   cabal update
   tmpdir=`mktemp -d`
   finaldir=`mktemp -d`
   cd $tmpdir
   tar xzf $HOME/.cabal/packages/hackage.haskell.org/00-index.tar.gz
   for dir in * ; do 
        if [ ! -d $dir ] ; then
            continue
        fi
        cd $dir
        lib=`ls --color=never -1 | tail -1`
        echo "************** Building package for $dir-$lib"
        cd $lib
        cabal2arch *.cabal > $dir.log 2>&1
        cd `find . -type d -a ! -name '.'`
        if makepkg -sm > ../$dir.log 2>&1 ; then
            echo "OK: " $dir-$lib
            cp *.pkg.tar.gz $finaldir/
            sudo pacman -A *.pkg.tar.gz
            rm *.pkg.tar.gz
            rm -rf pkg src *.tar.gz
            cd ..
            cp -R `find . -type d -a ! -name '.'` $finaldir/
            cp *.tar.gz $finaldir/
        else
            echo "Failed"
        fi
        cd $tmpdir
   done
   echo `ls $finaldir/*pkg* | wc -l` "build packages in $finaldir"
   echo "Now: scp -r $finaldir/* code.haskell.org:/srv/code/arch/$MACHTYPE/"


Using cabal-install we can get a topological sort of the installable graph of modules. You can see such an install plan here.

The Haskell Overlay

A suite of binary packages and PKGBULIDs of Haskell libraries is hosted on code.haskell.org by the Arch Haskell team:

  http://code.haskell.org/arch/

These are automatically generated via cabal2arch.