----------------------------------------------------------------------------- -- | -- Module : Distribution.Slackware.SlackBuild -- Copyright : (c) Andrea Rossato 2007 -- License : BSD3-style (see LICENSE) -- -- Maintainer : andrea.rossato@unibz.it -- Stability : stable -- Portability : portable -- -- -- HSlackBuilder is a script to automatically generate slackBuild -- scripts from a cabal package -- ----------------------------------------------------------------------------- module Distribution.Slackware.SlackBuild ( SlackBuildConfig (..) , defaultSlackBuildConfig , slackBuild , slackDoInst , slackDesc , slackRequired ) where import Data.Version ( showVersion ) import Distribution.Package import Distribution.PackageDescription import Distribution.Version data SlackBuildConfig = SBConfig { arch :: String , build :: Int , builder :: String , prefix :: String , setup :: String , runhaskell :: String , hoogle :: Bool , haddock :: Bool , linkSource :: Bool , hscolour :: String , usePrefix :: Bool , files :: [FilePath] } deriving Show defaultSlackBuildConfig :: SlackBuildConfig defaultSlackBuildConfig = SBConfig { arch = "i486" , build = 1 , builder = "hsb" , prefix = "/usr" , setup = "Setup.hs" , runhaskell = "runhaskell" , hoogle = False , haddock = True , linkSource = False , hscolour = [] , usePrefix = False , files = ["README"] } slackBuild :: SlackBuildConfig -> PackageDescription -> String slackBuild c d = unlines $ map unlines [ header , varSection , unpackSection , buildSection , stripSection , installSection , when (lib && hoogle c) hoogleSection , docSection , pkgSection ] where lib = hasLibs d name = case pkgName . package $ d of PackageName n -> n version = showVersion . pkgVersion . package $ d s = pad . setup $ c run = runhaskell c wrap l r m = l ++ m ++ r pad = wrap " " " " header = ["#!/bin/sh" , wrap "# Build" "for Slackware" . pad $ name , legalNotice ] varSection = [ "CWD=`pwd`" , "VERSION=" ++ version , wrap "ARCH=${ARCH:-" "}" (arch c) , wrap "BUILD=${BUILD:-" "}" (show (build c) ++ builder c) ] unpackSection = [ "PKG=/tmp/package-" ++ name , "rm -rf $PKG" , "mkdir $PKG" , "cd /tmp" , wrap "tar xzvf $CWD/" "-$VERSION.tar.gz" name , wrap "cd `basename " "-$VERSION i`" name ] buildSection = [ "chown -R root:root ." , unwords configure , wrap run "build" s , when (haddock c) $ unlines $ haddockGen lib , wrap run "copy --destdir=$PKG" s , when lib register ] configure = [ wrap run "configure --prefix=" s ++ prefix c , when lib "-p" ] haddockGen b = [ wrap run "haddock" s ++ when b " --executables" ++ when (linkSource c) " --hyperlink-source" ++ when (hscolour c /= []) " --hscolour-css=" ++ (hscolour c) , when (hoogle c) $ (wrap run "haddock --hoogle" s) ++ when b " --executables" ] register = wrap run "register --gen-script" s stripSection = [ "( cd $PKG" , " find . | xargs file | grep \"executable\" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null" , " find . | xargs file | grep \"shared object\" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null" , ")" , "gzip -9 $PKG/usr/man/man?/*" ] installSection = [ "mkdir -p $PKG/install" , "cat $CWD/doinst.sh > $PKG/install/doinst.sh" , "cat $CWD/slack-desc > $PKG/install/slack-desc" , when lib "cat register.sh > $PKG/install/register.sh" ] hoogleSection = [ "mkdir -p $PKG/var/spool/hoogle/" , "cp $PKG/usr/share/doc/" ++ name ++ "-$VERSION/html/" ++ name ++ "-$VERSION.txt $PKG/var/spool/hoogle/" ] docSection = [ wrap "mkdir -p $PKG/usr/doc/" "-$VERSION" name , "cp -a \\" , wrap " " " \\" (unwords otherFiles) , wrap " $PKG/usr/doc/" "-$VERSION" name ] otherFiles = licenseFile d : files c pkgSection = [ "cd $PKG" , wrap "makepkg -l y -c n ../" "-$VERSION-$ARCH-$BUILD.tgz" $ (when (usePrefix c) "hs-") ++ name ] legalNotice = "# This script has been generated by a computer programm\n" ++ "# and is not eligible for copyright protection.\n" slackDoInst :: SlackBuildConfig -> PackageDescription -> String slackDoInst c d = unlines [ when (hasLibs d) "( sh /install/register.sh ; rm /install/register.sh )" , when (haddock c && hoogle c) "( rm /var/spool/hoogle/hoogle ; cat /var/spool/hoogle/*txt >> /var/spool/hoogle/hoogle )" ] slackDesc :: SlackBuildConfig -> PackageDescription -> String slackDesc c d = format $ [ name , emptyLine , synopsis d , emptyLine , desc d , emptyLine ] ++ filter (not . null) [ concatIf (copyright d) "copyright:" , concatIf (author d) "author:" , concatIf (maintainer d) "maintainer:" , concatIf (homepage d) "homepage:" ] ++ endNote where desc = format . lines . description name = case pkgName . package $ d of PackageName n -> n concatIf p s = when (p /= []) (s ++ " " ++ p) format [] = [] format (x:xs) = when (usePrefix c) "hs-" ++ name ++ ": " ++ x ++ "\n" ++ format xs endNote = [ emptyLine , "Package created with HSlackBuilder" , "http://code.haskell.org/~arossato/hslackbuilder" ] emptyLine = [] slackRequired :: PackageDescription -> String slackRequired d = format [check p v | (Dependency p v) <- buildDepends d] where format = unlines . filter (not . null) check p v = when (needed p) $ (show p) ++ version v needed = not . flip elem ghc_packages . show version s | isAnyVersion s = [] | otherwise = show s when :: Bool -> [a] -> [a] when p x = if p then x else [] ghc_packages :: [String] ghc_packages = [ "Cabal" , "array" , "base" , "filepath" , "haskell98" , "parsec" , "readline" , "regex-base" , "regex-posix" , "regex-compat" , "stm" , "template-haskell" , "unix" , "bytestring" , "old-locale" , "old-time" , "process" , "containers" ]