blob: 52a5eacdd01c821d09adfb038bf9f3da675acf80 [file] [log] [blame] [edit]
--
-- Copyright 2016, NICTA
--
-- This software may be distributed and modified according to the terms of
-- the GNU General Public License version 2. Note that NO WARRANTY is provided.
-- See "LICENSE_GPLv2.txt" for details.
--
-- @TAG(NICTA_GPL)
--
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__ < 709
import Control.Applicative ((<$>))
#endif
import Control.Arrow (first)
import Control.Exception (SomeException, catch)
import Distribution.PackageDescription
import Distribution.Simple
#if MIN_VERSION_Cabal (2,0,0)
import Distribution.Simple.BuildPaths (autogenPackageModulesDir)
#else
import Distribution.Simple.BuildPaths (autogenModulesDir)
#endif
import Distribution.Simple.LocalBuildInfo as L
import qualified Distribution.Simple.Setup as S
import Distribution.Simple.Utils
import Distribution.PackageDescription
import Distribution.Verbosity (Verbosity)
import System.Directory(removeFile, doesDirectoryExist)
import System.Exit
import System.FilePath ((</>), (<.>), takeExtension)
import qualified System.FilePath.Posix as Px
import System.Process (readProcess)
-- Flags
isRelease :: S.ConfigFlags -> Bool
isRelease flags =
#if MIN_VERSION_Cabal (2,2,0)
case lookup (mkFlagName "release") (unFlagAssignment $ S.configConfigurationsFlags flags) of
#elif MIN_VERSION_Cabal (2,0,0)
case lookup (mkFlagName "release") (S.configConfigurationsFlags flags) of
#else
case lookup (FlagName "release") (S.configConfigurationsFlags flags) of
#endif
Just x -> x
Nothing -> False
-- Git Hash
gitHash :: IO String
gitHash = do h <- Control.Exception.catch (readProcess "git" ["rev-parse", "--short=10", "HEAD"] "")
(\e -> let e' = (e :: SomeException) in return "devel")
return $ takeWhile (/= '\n') h
-- Version Module
generateVersionModule verbosity dir release flags = do
hash <- gitHash
let versionModulePath = dir </> "Version_cogent" <.> "hs"
putStrLn $ "Generating " ++ versionModulePath ++
if release then " for release" else " for dev " ++ hash ++ "\n" ++
"(Configured with flags: " ++ flagsInfo ++ ")"
createDirectoryIfMissingVerbose verbosity True dir
#if MIN_VERSION_Cabal (2,0,0)
rewriteFileEx verbosity versionModulePath (versionModuleContents hash)
#else
rewriteFile versionModulePath (versionModuleContents hash)
#endif
where
flagsInfo = unwords (flip map flags (\(f,a) -> (if a then "+" else "-") ++ f))
versionModuleContents h = "module Version_cogent where\n\n" ++
"gitHash :: String\n" ++
(if release
then "gitHash = \"\"\n"
else "gitHash = \"" ++ h ++ "\"\n") ++
"configFlags :: String" ++ "\n" ++
"configFlags = \"Built with flags: " ++ flagsInfo ++ "\""
-- Configure
cogentConfigure :: Args -> S.ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()
cogentConfigure _ flags _ lbi = do
#if MIN_VERSION_Cabal (2,0,0)
generateVersionModule verbosity (autogenPackageModulesDir lbi) (isRelease (configFlags lbi)) flagAssignment
#else
generateVersionModule verbosity (autogenModulesDir lbi) (isRelease (configFlags lbi)) flagAssignment
#endif
where
verbosity = S.fromFlag $ S.configVerbosity flags
version = pkgVersion . package $ localPkgDescr lbi
#if MIN_VERSION_Cabal (2,2,0)
flagAssignment = map (first unFlagName) $ unFlagAssignment $ S.configConfigurationsFlags flags
#else
flagAssignment = map (first unFlagName) $ S.configConfigurationsFlags flags
#endif
-- Copy
copyGumHdrs :: Verbosity -> PackageDescription -> LocalBuildInfo -> CopyDest -> IO ()
copyGumHdrs verbosity pkg lbi copy = do
let hdrsdest = datadir (L.absoluteInstallDirs pkg lbi copy) </> "include"
putStrLn $ "Installing Gum headers in `" ++ hdrsdest ++ "'..."
createDirectoryIfMissingVerbose verbosity True hdrsdest
errorMsg <- installDirectoryContents verbosity "lib" hdrsdest
case errorMsg of
Nothing -> return ()
Just x -> do putStrLn x; putStrLn "Are you using cabal2.4?"
where
-- This function is copied from Cabal-1.24.2.0 and modified
installDirectoryContents :: Verbosity -> FilePath -> FilePath -> IO (Maybe String)
installDirectoryContents verbosity srcDir destDir = do
info verbosity ("copy directory '" ++ srcDir ++ "' to '" ++ destDir ++ "'...")
b <- doesDirectoryExist srcDir
b' <- doesDirectoryExist destDir
if not b then do
return $ Just $ "Error: Source directory '" ++ srcDir ++ "' not found"
else do
if not b' then do
return $ Just $ "Error: Destination directory '" ++ destDir ++ "' not found"
else do
srcFiles <- getDirectoryContentsRecursive srcDir
let srcFiles' = filter ((`elem` [".ac", ".ah", ".h", ".cogent", ".c"]) . takeExtension) srcFiles
installOrdinaryFiles verbosity destDir [ (srcDir, f) | f <- srcFiles' ]
return Nothing
installManPage :: Verbosity -> PackageDescription -> LocalBuildInfo -> CopyDest -> IO ()
installManPage verbosity pkg lbi copy = do
let mandest = mandir (L.absoluteInstallDirs pkg lbi copy) ++ "/man1"
putStrLn $ "Installing man page to `" ++ mandest ++ "'..."
r <- rawSystemExitCode verbosity "perl" ["scripts/man-gen.pl", mandest, buildDir lbi </> "cogent/cogent"]
case r of
ExitSuccess -> return ()
ExitFailure n -> putStrLn $ "Installing man page failed: exit code " ++ show n
-- Test
-- cabal has two unrelated "dataDir" variables.
-- We need to use the one in the install directory where cogent is installed.
fixPkg pkg target = pkg { dataDir = target }
-- "Args" argument of testHooks have been added in cabal 1.22.0
#if __GLASGOW_HASKELL__ < 710
originalTestHook _ = testHook simpleUserHooks
#else
originalTestHook = testHook simpleUserHooks
#endif
cogentTestHook args pkg lbi hooks flags = do
let target = datadir $ L.absoluteInstallDirs pkg lbi NoCopyDest
originalTestHook args (fixPkg pkg target) lbi hooks flags
-- -----
-- Main
-- -----
main = defaultMainWithHooks $ autoconfUserHooks
{ postConf = cogentConfigure
-- TODO:
-- , postBuild = \_ flags pkg lbi -> do
-- copyGumHdrs
-- buildManPage
, postCopy = \_ flags pkg lbi -> do
copyGumHdrs (S.fromFlag $ S.copyVerbosity flags) pkg lbi (S.fromFlag $ S.copyDest flags)
installManPage (S.fromFlag $ S.copyVerbosity flags) pkg lbi (S.fromFlag $ S.copyDest flags)
-- No idea why `postInst' is needed, as it doesn't seem to execute.
-- Looking at other packages, they mostly do the same.
-- Googled for quite a while and found some questions but no answers. / zilinc
, postInst = \_ flags pkg lbi -> do
installManPage (S.fromFlag $ S.installVerbosity flags) pkg lbi NoCopyDest
#if __GLASGOW_HASKELL__ < 710
, testHook = cogentTestHook ()
#else
, testHook = cogentTestHook
#endif
}