shaker-0.1: src/Shaker/Action/Compile.hs
module Shaker.Action.Compile(
runCompile
,runFullCompile
)
where
import Data.List
import GHC
import DynFlags
import GHC.Paths
import Shaker.Io
import Shaker.Type
import Control.Monad.Trans
import Control.Monad.Reader
-- |Run haskell compilation on given file input
runCompile :: Plugin
runCompile = asks compileInputs >>= mapM runSingleCompileInput >> return ()
runSingleCompileInput :: CompileInput -> Shaker IO()
runSingleCompileInput (CompileInput sourceDir desc targetInput procFlags strflags inputTargetFiles) = do
lift $ putStrLn "-------------------------------------"
lift $ putStrLn $ concat [" --------- ", desc," ---------"]
targetFiles <- checkTargetFiles inputTargetFiles
lift $ putStrLn $ concat [" --------- ", "Compiling target : "++ show targetFiles," ---------"]
lift $ defaultErrorHandler defaultDynFlags $
runGhc (Just libdir) $ do
dflags <- getSessionDynFlags
(newFlags,_,_) <- parseDynamicFlags dflags (map noLoc strflags)
_ <- setSessionDynFlags $ procFlags $ setSourceAndTarget sourceDir targetInput newFlags
target <- mapM (`guessTarget` Nothing) targetFiles
setTargets target
_ <- load LoadAllTargets
return ()
runFullCompile :: Plugin
runFullCompile = setCompileInputForAllHsSources >>= \a ->
runSingleCompileInput a >>
return ()
-- | Fill the target files to all files in listenerInput if empty
checkTargetFiles :: [String] -> Shaker IO([String])
checkTargetFiles [] = do
(ListenerInput fli _) <- asks listenerInput
files <- lift $ recurseMultipleListFiles fli
lift $ filterM (\a -> not `liftM` isFileContainingMain a) files
checkTargetFiles l = return l
setSourceAndTarget :: [String] -> String ->DynFlags -> DynFlags
setSourceAndTarget sources target dflags = dflags{
importPaths = sources
,objectDir = Just target
,hiDir = Just target
}
setCompileInputForAllHsSources :: Shaker IO CompileInput
setCompileInputForAllHsSources = do
(cpIn:_) <- asks compileInputs
filePaths <- lift $ recurseMultipleListFiles $ map (\a -> FileListenInfo a defaultExclude defaultHaskellPatterns ) (cfSourceDirs cpIn)
toExcludeFiles <- lift $ filterM isFileContainingMain filePaths
return $ cpIn {cfTargetFiles = filePaths \\ toExcludeFiles , cfDescription ="Full compilation" }