{-# LANGUAGE CPP #-}
module Foreign.Hoppy.Setup (
ProjectConfig (..),
cppMain,
cppUserHooks,
hsMain,
hsUserHooks,
) where
import Control.Monad (unless, when)
import Data.List (isInfixOf)
import Distribution.InstalledPackageInfo (libraryDirs)
#if MIN_VERSION_Cabal(2,0,0)
import Distribution.Package (mkPackageName)
#else
import Distribution.Package (PackageName (PackageName))
#endif
import Distribution.PackageDescription (
HookedBuildInfo,
PackageDescription,
emptyBuildInfo,
extraLibDirs,
)
import Distribution.Simple (defaultMainWithHooks, simpleUserHooks)
import Distribution.Simple.LocalBuildInfo (
LocalBuildInfo,
absoluteInstallDirs,
buildDir,
installedPkgs,
libdir,
withPrograms,
)
import Distribution.Simple.PackageIndex (lookupPackageName)
import Distribution.Simple.Program (
runDbProgram,
runProgram,
)
import Distribution.Simple.Program.Find (
ProgramSearchPathEntry (ProgramSearchPathDefault),
findProgramOnSearchPath,
)
import Distribution.Simple.Program.Types (
ConfiguredProgram,
Program,
ProgramLocation (FoundOnSystem),
simpleConfiguredProgram,
simpleProgram,
)
import Distribution.Simple.Setup (
CopyDest (CopyTo, NoCopyDest),
RegisterFlags,
buildVerbosity,
cleanVerbosity,
configVerbosity,
copyDest,
copyVerbosity,
flagToMaybe,
fromFlagOrDefault,
installDistPref,
installVerbosity,
regInPlace,
regVerbosity,
)
import Distribution.Simple.UserHooks (
UserHooks (
buildHook,
hookedPrograms,
cleanHook,
copyHook,
instHook,
regHook,
postConf,
preBuild,
preCopy,
preInst,
preReg,
preRepl,
preTest
),
)
#if MIN_VERSION_Cabal(2,0,0)
import Distribution.Simple.Utils (die')
#else
import Distribution.Simple.Utils (die)
#endif
import Distribution.Simple.Utils (installOrdinaryFile)
import Distribution.Verbosity (Verbosity, normal)
import Foreign.Hoppy.Generator.Main (run)
import Foreign.Hoppy.Generator.Spec (Interface)
import System.Directory (createDirectoryIfMissing, doesFileExist)
import System.FilePath ((</>), takeDirectory)
data ProjectConfig = ProjectConfig
{ ProjectConfig -> Either String Interface
interfaceResult :: Either String Interface
, ProjectConfig -> String
cppPackageName :: String
, ProjectConfig -> String
cppSourcesDir :: FilePath
, ProjectConfig -> String
hsSourcesDir :: FilePath
}
enumEvalCacheFileName :: FilePath
enumEvalCacheFileName :: String
enumEvalCacheFileName = String
"hoppy-enum-eval-cache"
getInterface :: ProjectConfig -> Verbosity -> IO Interface
getInterface :: ProjectConfig -> Verbosity -> IO Interface
getInterface ProjectConfig
project Verbosity
verbosity = case ProjectConfig -> Either String Interface
interfaceResult ProjectConfig
project of
Left String
errorMsg ->
#if MIN_VERSION_Cabal(2,0,0)
Verbosity -> String -> IO Interface
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity (String -> IO Interface) -> String -> IO Interface
forall a b. (a -> b) -> a -> b
$
#else
die $
#endif
String
"Error initializing interface: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
errorMsg
Right Interface
iface -> Interface -> IO Interface
forall (m :: * -> *) a. Monad m => a -> m a
return Interface
iface
cppMain :: ProjectConfig -> IO ()
cppMain :: ProjectConfig -> IO ()
cppMain ProjectConfig
project = UserHooks -> IO ()
defaultMainWithHooks (UserHooks -> IO ()) -> UserHooks -> IO ()
forall a b. (a -> b) -> a -> b
$ ProjectConfig -> UserHooks
cppUserHooks ProjectConfig
project
cppUserHooks :: ProjectConfig -> UserHooks
cppUserHooks :: ProjectConfig -> UserHooks
cppUserHooks ProjectConfig
project =
UserHooks
simpleUserHooks
{ hookedPrograms :: [Program]
hookedPrograms = [Program
makeProgram]
, postConf :: Args
-> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()
postConf = \Args
args ConfigFlags
flags PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo -> do
let verbosity :: Verbosity
verbosity = Verbosity -> Flag Verbosity -> Verbosity
forall a. a -> Flag a -> a
fromFlagOrDefault Verbosity
normal (Flag Verbosity -> Verbosity) -> Flag Verbosity -> Verbosity
forall a b. (a -> b) -> a -> b
$ ConfigFlags -> Flag Verbosity
configVerbosity ConfigFlags
flags
ProjectConfig -> Verbosity -> LocalBuildInfo -> IO ()
cppConfigure ProjectConfig
project Verbosity
verbosity LocalBuildInfo
localBuildInfo
UserHooks
-> Args
-> ConfigFlags
-> PackageDescription
-> LocalBuildInfo
-> IO ()
postConf UserHooks
simpleUserHooks Args
args ConfigFlags
flags PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo
, buildHook :: PackageDescription
-> LocalBuildInfo -> UserHooks -> BuildFlags -> IO ()
buildHook = \PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo UserHooks
hooks BuildFlags
flags -> do
UserHooks
-> PackageDescription
-> LocalBuildInfo
-> UserHooks
-> BuildFlags
-> IO ()
buildHook UserHooks
simpleUserHooks PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo UserHooks
hooks BuildFlags
flags
let verbosity :: Verbosity
verbosity = Verbosity -> Flag Verbosity -> Verbosity
forall a. a -> Flag a -> a
fromFlagOrDefault Verbosity
normal (Flag Verbosity -> Verbosity) -> Flag Verbosity -> Verbosity
forall a b. (a -> b) -> a -> b
$ BuildFlags -> Flag Verbosity
buildVerbosity BuildFlags
flags
Verbosity -> LocalBuildInfo -> IO ()
cppBuild Verbosity
verbosity LocalBuildInfo
localBuildInfo
, copyHook :: PackageDescription
-> LocalBuildInfo -> UserHooks -> CopyFlags -> IO ()
copyHook = \PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo UserHooks
hooks CopyFlags
flags -> do
UserHooks
-> PackageDescription
-> LocalBuildInfo
-> UserHooks
-> CopyFlags
-> IO ()
copyHook UserHooks
simpleUserHooks PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo UserHooks
hooks CopyFlags
flags
let verbosity :: Verbosity
verbosity = Verbosity -> Flag Verbosity -> Verbosity
forall a. a -> Flag a -> a
fromFlagOrDefault Verbosity
normal (Flag Verbosity -> Verbosity) -> Flag Verbosity -> Verbosity
forall a b. (a -> b) -> a -> b
$ CopyFlags -> Flag Verbosity
copyVerbosity CopyFlags
flags
dest :: CopyDest
dest = CopyDest -> Flag CopyDest -> CopyDest
forall a. a -> Flag a -> a
fromFlagOrDefault CopyDest
NoCopyDest (Flag CopyDest -> CopyDest) -> Flag CopyDest -> CopyDest
forall a b. (a -> b) -> a -> b
$ CopyFlags -> Flag CopyDest
copyDest CopyFlags
flags
Verbosity
-> PackageDescription -> LocalBuildInfo -> CopyDest -> IO ()
cppInstall Verbosity
verbosity PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo CopyDest
dest
, instHook :: PackageDescription
-> LocalBuildInfo -> UserHooks -> InstallFlags -> IO ()
instHook = \PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo UserHooks
hooks InstallFlags
flags -> do
UserHooks
-> PackageDescription
-> LocalBuildInfo
-> UserHooks
-> InstallFlags
-> IO ()
instHook UserHooks
simpleUserHooks PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo UserHooks
hooks InstallFlags
flags
let verbosity :: Verbosity
verbosity = Verbosity -> Flag Verbosity -> Verbosity
forall a. a -> Flag a -> a
fromFlagOrDefault Verbosity
normal (Flag Verbosity -> Verbosity) -> Flag Verbosity -> Verbosity
forall a b. (a -> b) -> a -> b
$ InstallFlags -> Flag Verbosity
installVerbosity InstallFlags
flags
dest :: CopyDest
dest = CopyDest -> (String -> CopyDest) -> Maybe String -> CopyDest
forall b a. b -> (a -> b) -> Maybe a -> b
maybe CopyDest
NoCopyDest String -> CopyDest
CopyTo (Maybe String -> CopyDest) -> Maybe String -> CopyDest
forall a b. (a -> b) -> a -> b
$
Flag String -> Maybe String
forall a. Flag a -> Maybe a
flagToMaybe (Flag String -> Maybe String) -> Flag String -> Maybe String
forall a b. (a -> b) -> a -> b
$ InstallFlags -> Flag String
installDistPref InstallFlags
flags
Verbosity
-> PackageDescription -> LocalBuildInfo -> CopyDest -> IO ()
cppInstall Verbosity
verbosity PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo CopyDest
dest
, regHook :: PackageDescription
-> LocalBuildInfo -> UserHooks -> RegisterFlags -> IO ()
regHook = \PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo UserHooks
hooks RegisterFlags
flags -> do
UserHooks
-> PackageDescription
-> LocalBuildInfo
-> UserHooks
-> RegisterFlags
-> IO ()
regHook UserHooks
simpleUserHooks PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo UserHooks
hooks RegisterFlags
flags
let verbosity :: Verbosity
verbosity = Verbosity -> Flag Verbosity -> Verbosity
forall a. a -> Flag a -> a
fromFlagOrDefault Verbosity
normal (Flag Verbosity -> Verbosity) -> Flag Verbosity -> Verbosity
forall a b. (a -> b) -> a -> b
$ RegisterFlags -> Flag Verbosity
regVerbosity RegisterFlags
flags
Verbosity -> LocalBuildInfo -> RegisterFlags -> IO ()
cppRegister Verbosity
verbosity LocalBuildInfo
localBuildInfo RegisterFlags
flags
, cleanHook :: PackageDescription -> () -> UserHooks -> CleanFlags -> IO ()
cleanHook = \PackageDescription
pkgDesc ()
z UserHooks
hooks CleanFlags
flags -> do
UserHooks
-> PackageDescription -> () -> UserHooks -> CleanFlags -> IO ()
cleanHook UserHooks
simpleUserHooks PackageDescription
pkgDesc ()
z UserHooks
hooks CleanFlags
flags
let verbosity :: Verbosity
verbosity = Verbosity -> Flag Verbosity -> Verbosity
forall a. a -> Flag a -> a
fromFlagOrDefault Verbosity
normal (Flag Verbosity -> Verbosity) -> Flag Verbosity -> Verbosity
forall a b. (a -> b) -> a -> b
$ CleanFlags -> Flag Verbosity
cleanVerbosity CleanFlags
flags
ProjectConfig -> Verbosity -> IO ()
cppClean ProjectConfig
project Verbosity
verbosity
}
makeProgram :: Program
makeProgram :: Program
makeProgram = String -> Program
simpleProgram String
"make"
cppConfigure :: ProjectConfig -> Verbosity -> LocalBuildInfo -> IO ()
cppConfigure :: ProjectConfig -> Verbosity -> LocalBuildInfo -> IO ()
cppConfigure ProjectConfig
project Verbosity
verbosity LocalBuildInfo
localBuildInfo = do
let sourcesDir :: String
sourcesDir = ProjectConfig -> String
cppSourcesDir ProjectConfig
project
Interface
iface <- ProjectConfig -> Verbosity -> IO Interface
getInterface ProjectConfig
project Verbosity
verbosity
Bool -> String -> IO ()
createDirectoryIfMissing Bool
True String
sourcesDir
Bool -> String -> IO ()
createDirectoryIfMissing Bool
True (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ LocalBuildInfo -> String
buildDir LocalBuildInfo
localBuildInfo
[Action]
_ <- [Interface] -> Args -> IO [Action]
run [Interface
iface]
[ String
"--enum-eval-cache-mode", String
"refresh"
, String
"--enum-eval-cache-path", LocalBuildInfo -> String
buildDir LocalBuildInfo
localBuildInfo String -> String -> String
</> String
enumEvalCacheFileName
, String
"--gen-cpp", String
sourcesDir
]
Maybe ConfiguredProgram
maybeConfigureProgram <- IO (Maybe ConfiguredProgram)
findConfigure
case Maybe ConfiguredProgram
maybeConfigureProgram of
Just ConfiguredProgram
configureProgram -> Verbosity -> ConfiguredProgram -> Args -> IO ()
runProgram Verbosity
verbosity ConfiguredProgram
configureProgram []
Maybe ConfiguredProgram
Nothing -> () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
where findConfigure :: IO (Maybe ConfiguredProgram)
findConfigure :: IO (Maybe ConfiguredProgram)
findConfigure = do
Bool
hasConfigure <- String -> IO Bool
doesFileExist String
"configure"
Maybe ConfiguredProgram -> IO (Maybe ConfiguredProgram)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ConfiguredProgram -> IO (Maybe ConfiguredProgram))
-> Maybe ConfiguredProgram -> IO (Maybe ConfiguredProgram)
forall a b. (a -> b) -> a -> b
$ if Bool
hasConfigure
then ConfiguredProgram -> Maybe ConfiguredProgram
forall a. a -> Maybe a
Just (ConfiguredProgram -> Maybe ConfiguredProgram)
-> ConfiguredProgram -> Maybe ConfiguredProgram
forall a b. (a -> b) -> a -> b
$ String -> ProgramLocation -> ConfiguredProgram
simpleConfiguredProgram String
"configure" (ProgramLocation -> ConfiguredProgram)
-> ProgramLocation -> ConfiguredProgram
forall a b. (a -> b) -> a -> b
$ String -> ProgramLocation
FoundOnSystem String
"./configure"
else Maybe ConfiguredProgram
forall a. Maybe a
Nothing
cppBuild :: Verbosity -> LocalBuildInfo -> IO ()
cppBuild :: Verbosity -> LocalBuildInfo -> IO ()
cppBuild Verbosity
verbosity LocalBuildInfo
localBuildInfo = do
Bool
hasMakefile <- String -> IO Bool
doesFileExist String
"Makefile"
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
hasMakefile (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
#if MIN_VERSION_Cabal(2,0,0)
Verbosity -> String -> IO ()
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity
#else
die
#endif
String
"No Makefile found."
let programDb :: ProgramDb
programDb = LocalBuildInfo -> ProgramDb
withPrograms LocalBuildInfo
localBuildInfo
Verbosity -> Program -> ProgramDb -> Args -> IO ()
runDbProgram Verbosity
verbosity Program
makeProgram ProgramDb
programDb []
cppInstall :: Verbosity -> PackageDescription -> LocalBuildInfo -> CopyDest -> IO ()
cppInstall :: Verbosity
-> PackageDescription -> LocalBuildInfo -> CopyDest -> IO ()
cppInstall Verbosity
verbosity PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo CopyDest
dest = do
Bool
hasMakefile <- String -> IO Bool
doesFileExist String
"Makefile"
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
hasMakefile (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
#if MIN_VERSION_Cabal(2,0,0)
Verbosity -> String -> IO ()
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity
#else
die
#endif
String
"No Makefile found."
let programDb :: ProgramDb
programDb = LocalBuildInfo -> ProgramDb
withPrograms LocalBuildInfo
localBuildInfo
libDir :: String
libDir = InstallDirs String -> String
forall dir. InstallDirs dir -> dir
libdir (InstallDirs String -> String) -> InstallDirs String -> String
forall a b. (a -> b) -> a -> b
$ PackageDescription
-> LocalBuildInfo -> CopyDest -> InstallDirs String
absoluteInstallDirs PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo CopyDest
dest
Bool -> String -> IO ()
createDirectoryIfMissing Bool
True String
libDir
Verbosity -> Program -> ProgramDb -> Args -> IO ()
runDbProgram Verbosity
verbosity Program
makeProgram ProgramDb
programDb [String
"install", String
"libdir=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
libDir]
let enumEvalCacheFilePath :: String
enumEvalCacheFilePath = LocalBuildInfo -> String
buildDir LocalBuildInfo
localBuildInfo String -> String -> String
</> String
enumEvalCacheFileName
Bool
enumEvalCacheExists <- String -> IO Bool
doesFileExist String
enumEvalCacheFilePath
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
enumEvalCacheExists (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
Verbosity -> String -> String -> IO ()
installOrdinaryFile Verbosity
verbosity
String
enumEvalCacheFilePath
(String
libDir String -> String -> String
</> String
enumEvalCacheFileName)
cppRegister :: Verbosity -> LocalBuildInfo -> RegisterFlags -> IO ()
cppRegister :: Verbosity -> LocalBuildInfo -> RegisterFlags -> IO ()
cppRegister Verbosity
verbosity LocalBuildInfo
localBuildInfo RegisterFlags
flags = do
Bool
hasMakefile <- String -> IO Bool
doesFileExist String
"Makefile"
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
hasMakefile (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
#if MIN_VERSION_Cabal(2,0,0)
Verbosity -> String -> IO ()
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity
#else
die
#endif
String
"No Makefile found."
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Flag Bool -> Bool
forall a. a -> Flag a -> a
fromFlagOrDefault Bool
False (RegisterFlags -> Flag Bool
regInPlace RegisterFlags
flags)) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
let programDb :: ProgramDb
programDb = LocalBuildInfo -> ProgramDb
withPrograms LocalBuildInfo
localBuildInfo
libDir :: String
libDir = LocalBuildInfo -> String
buildDir LocalBuildInfo
localBuildInfo
Bool -> String -> IO ()
createDirectoryIfMissing Bool
True String
libDir
Verbosity -> Program -> ProgramDb -> Args -> IO ()
runDbProgram Verbosity
verbosity Program
makeProgram ProgramDb
programDb [String
"install", String
"libdir=" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
libDir]
cppClean :: ProjectConfig -> Verbosity -> IO ()
cppClean :: ProjectConfig -> Verbosity -> IO ()
cppClean ProjectConfig
project Verbosity
verbosity = do
Interface
iface <- ProjectConfig -> Verbosity -> IO Interface
getInterface ProjectConfig
project Verbosity
verbosity
[Action]
_ <- [Interface] -> Args -> IO [Action]
run [Interface
iface] [String
"--clean-cpp", ProjectConfig -> String
cppSourcesDir ProjectConfig
project]
Bool
hasMakefile <- String -> IO Bool
doesFileExist String
"Makefile"
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
hasMakefile (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
#if MIN_VERSION_Cabal(2,0,0)
Verbosity -> String -> IO ()
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity
#else
die
#endif
String
"No Makefile found."
ConfiguredProgram
make <- Verbosity -> String -> IO ConfiguredProgram
findSystemProgram Verbosity
verbosity String
"make"
Verbosity -> ConfiguredProgram -> Args -> IO ()
runProgram Verbosity
verbosity ConfiguredProgram
make [String
"clean"]
findSystemProgram :: Verbosity -> FilePath -> IO ConfiguredProgram
findSystemProgram :: Verbosity -> String -> IO ConfiguredProgram
findSystemProgram Verbosity
verbosity String
basename = do
Maybe String
maybePath <-
#if MIN_VERSION_Cabal(1,24,0)
(Maybe (String, Args) -> Maybe String)
-> IO (Maybe (String, Args)) -> IO (Maybe String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((String, Args) -> String) -> Maybe (String, Args) -> Maybe String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String, Args) -> String
forall a b. (a, b) -> a
fst) (IO (Maybe (String, Args)) -> IO (Maybe String))
-> IO (Maybe (String, Args)) -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$
#endif
Verbosity
-> ProgramSearchPath -> String -> IO (Maybe (String, Args))
findProgramOnSearchPath Verbosity
verbosity [ProgramSearchPathEntry
ProgramSearchPathDefault] String
basename
case Maybe String
maybePath of
Just String
path -> ConfiguredProgram -> IO ConfiguredProgram
forall (m :: * -> *) a. Monad m => a -> m a
return (ConfiguredProgram -> IO ConfiguredProgram)
-> ConfiguredProgram -> IO ConfiguredProgram
forall a b. (a -> b) -> a -> b
$ String -> ProgramLocation -> ConfiguredProgram
simpleConfiguredProgram String
basename (ProgramLocation -> ConfiguredProgram)
-> ProgramLocation -> ConfiguredProgram
forall a b. (a -> b) -> a -> b
$ String -> ProgramLocation
FoundOnSystem String
path
Maybe String
Nothing ->
#if MIN_VERSION_Cabal(2,0,0)
Verbosity -> String -> IO ConfiguredProgram
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity (String -> IO ConfiguredProgram) -> String -> IO ConfiguredProgram
forall a b. (a -> b) -> a -> b
$
#else
die $
#endif
String
"Couldn't find program " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
basename String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"."
hsMain :: ProjectConfig -> IO ()
hsMain :: ProjectConfig -> IO ()
hsMain ProjectConfig
project = UserHooks -> IO ()
defaultMainWithHooks (UserHooks -> IO ()) -> UserHooks -> IO ()
forall a b. (a -> b) -> a -> b
$ ProjectConfig -> UserHooks
hsUserHooks ProjectConfig
project
hsUserHooks :: ProjectConfig -> UserHooks
hsUserHooks :: ProjectConfig -> UserHooks
hsUserHooks ProjectConfig
project =
UserHooks
simpleUserHooks
{ postConf :: Args
-> ConfigFlags -> PackageDescription -> LocalBuildInfo -> IO ()
postConf = \Args
args ConfigFlags
flags PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo -> do
UserHooks
-> Args
-> ConfigFlags
-> PackageDescription
-> LocalBuildInfo
-> IO ()
postConf UserHooks
simpleUserHooks Args
args ConfigFlags
flags PackageDescription
pkgDesc LocalBuildInfo
localBuildInfo
let verbosity :: Verbosity
verbosity = Verbosity -> Flag Verbosity -> Verbosity
forall a. a -> Flag a -> a
fromFlagOrDefault Verbosity
normal (Flag Verbosity -> Verbosity) -> Flag Verbosity -> Verbosity
forall a b. (a -> b) -> a -> b
$ ConfigFlags -> Flag Verbosity
configVerbosity ConfigFlags
flags
ProjectConfig -> Verbosity -> LocalBuildInfo -> IO ()
hsConfigure ProjectConfig
project Verbosity
verbosity LocalBuildInfo
localBuildInfo
, preBuild :: Args -> BuildFlags -> IO HookedBuildInfo
preBuild = \Args
_ BuildFlags
_ -> IO HookedBuildInfo
addLibDir
, preTest :: Args -> TestFlags -> IO HookedBuildInfo
preTest = \Args
_ TestFlags
_ -> IO HookedBuildInfo
addLibDir
, preCopy :: Args -> CopyFlags -> IO HookedBuildInfo
preCopy = \Args
_ CopyFlags
_ -> IO HookedBuildInfo
addLibDir
, preInst :: Args -> InstallFlags -> IO HookedBuildInfo
preInst = \Args
_ InstallFlags
_ -> IO HookedBuildInfo
addLibDir
, preReg :: Args -> RegisterFlags -> IO HookedBuildInfo
preReg = \Args
_ RegisterFlags
_ -> IO HookedBuildInfo
addLibDir
, preRepl :: Args -> ReplFlags -> IO HookedBuildInfo
preRepl = \Args
_ ReplFlags
_ -> IO HookedBuildInfo
addLibDir
, cleanHook :: PackageDescription -> () -> UserHooks -> CleanFlags -> IO ()
cleanHook = \PackageDescription
pkgDesc ()
z UserHooks
hooks CleanFlags
flags -> do
UserHooks
-> PackageDescription -> () -> UserHooks -> CleanFlags -> IO ()
cleanHook UserHooks
simpleUserHooks PackageDescription
pkgDesc ()
z UserHooks
hooks CleanFlags
flags
let verbosity :: Verbosity
verbosity = Verbosity -> Flag Verbosity -> Verbosity
forall a. a -> Flag a -> a
fromFlagOrDefault Verbosity
normal (Flag Verbosity -> Verbosity) -> Flag Verbosity -> Verbosity
forall a b. (a -> b) -> a -> b
$ CleanFlags -> Flag Verbosity
cleanVerbosity CleanFlags
flags
ProjectConfig -> Verbosity -> IO ()
hsClean ProjectConfig
project Verbosity
verbosity
}
hsCppLibDirFile :: FilePath
hsCppLibDirFile :: String
hsCppLibDirFile = String
"dist/build/hoppy-cpp-libdir"
hsConfigure :: ProjectConfig -> Verbosity -> LocalBuildInfo -> IO ()
hsConfigure :: ProjectConfig -> Verbosity -> LocalBuildInfo -> IO ()
hsConfigure ProjectConfig
project Verbosity
verbosity LocalBuildInfo
localBuildInfo = do
Interface
iface <- ProjectConfig -> Verbosity -> IO Interface
getInterface ProjectConfig
project Verbosity
verbosity
String
libDir <- IO String
lookupCppLibDir
String -> IO ()
storeCppLibDir String
libDir
Interface -> String -> IO ()
generateSources Interface
iface String
libDir
where lookupCppLibDir :: IO String
lookupCppLibDir = do
let packageName :: String
packageName = ProjectConfig -> String
cppPackageName ProjectConfig
project
InstalledPackageInfo
cppPkg <- case PackageIndex InstalledPackageInfo
-> PackageName -> [(Version, [InstalledPackageInfo])]
forall a. PackageIndex a -> PackageName -> [(Version, [a])]
lookupPackageName (LocalBuildInfo -> PackageIndex InstalledPackageInfo
installedPkgs LocalBuildInfo
localBuildInfo) (PackageName -> [(Version, [InstalledPackageInfo])])
-> PackageName -> [(Version, [InstalledPackageInfo])]
forall a b. (a -> b) -> a -> b
$
#if MIN_VERSION_Cabal(2,0,0)
String -> PackageName
mkPackageName String
packageName
#else
PackageName packageName
#endif
of
[(Version
_, [InstalledPackageInfo
pkg])] -> InstalledPackageInfo -> IO InstalledPackageInfo
forall (m :: * -> *) a. Monad m => a -> m a
return InstalledPackageInfo
pkg
[(Version, [InstalledPackageInfo])]
results ->
#if MIN_VERSION_Cabal(2,0,0)
Verbosity -> String -> IO InstalledPackageInfo
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity (String -> IO InstalledPackageInfo)
-> String -> IO InstalledPackageInfo
forall a b. (a -> b) -> a -> b
$
#else
die $
#endif
String
"Failed to find a unique " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
packageName String -> String -> String
forall a. [a] -> [a] -> [a]
++
String
" installation. Found " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Version, [InstalledPackageInfo])] -> String
forall a. Show a => a -> String
show [(Version, [InstalledPackageInfo])]
results String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"."
case (String -> Bool) -> Args -> Args
forall a. (a -> Bool) -> [a] -> [a]
filter (\String
x -> String
packageName String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isInfixOf` String
x) (Args -> Args) -> Args -> Args
forall a b. (a -> b) -> a -> b
$ InstalledPackageInfo -> Args
libraryDirs InstalledPackageInfo
cppPkg of
[String
libDir] -> String -> IO String
forall (m :: * -> *) a. Monad m => a -> m a
return String
libDir
Args
libDirs ->
#if MIN_VERSION_Cabal(2,0,0)
Verbosity -> String -> IO String
forall a. Verbosity -> String -> IO a
die' Verbosity
verbosity (String -> IO String) -> String -> IO String
forall a b. (a -> b) -> a -> b
$
#else
die $
#endif
String
"Expected a single library directory for " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
packageName String -> String -> String
forall a. [a] -> [a] -> [a]
++
String
", got " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Args -> String
forall a. Show a => a -> String
show Args
libDirs String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"."
storeCppLibDir :: String -> IO ()
storeCppLibDir String
libDir = do
Bool -> String -> IO ()
createDirectoryIfMissing Bool
True (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> String
takeDirectory String
hsCppLibDirFile
String -> String -> IO ()
writeFile String
hsCppLibDirFile String
libDir
generateSources :: Interface -> String -> IO ()
generateSources Interface
iface String
libDir = do
let sourcesDir :: String
sourcesDir = ProjectConfig -> String
hsSourcesDir ProjectConfig
project
Bool -> String -> IO ()
createDirectoryIfMissing Bool
True String
sourcesDir
[Action]
_ <- [Interface] -> Args -> IO [Action]
run [Interface
iface]
[ String
"--enum-eval-cache-mode", String
"must-exist"
, String
"--enum-eval-cache-path", String
libDir String -> String -> String
</> String
enumEvalCacheFileName
, String
"--gen-hs", String
sourcesDir
]
() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
addLibDir :: IO HookedBuildInfo
addLibDir :: IO HookedBuildInfo
addLibDir = do
String
libDir <- String -> IO String
readFile String
hsCppLibDirFile
HookedBuildInfo -> IO HookedBuildInfo
forall (m :: * -> *) a. Monad m => a -> m a
return (BuildInfo -> Maybe BuildInfo
forall a. a -> Maybe a
Just BuildInfo
emptyBuildInfo {extraLibDirs :: Args
extraLibDirs = [String
libDir]}, [])
hsClean :: ProjectConfig -> Verbosity -> IO ()
hsClean :: ProjectConfig -> Verbosity -> IO ()
hsClean ProjectConfig
project Verbosity
verbosity = do
Interface
iface <- ProjectConfig -> Verbosity -> IO Interface
getInterface ProjectConfig
project Verbosity
verbosity
[Action]
_ <- [Interface] -> Args -> IO [Action]
run [Interface
iface] [String
"--clean-hs", ProjectConfig -> String
hsSourcesDir ProjectConfig
project]
() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()