ddc-war-0.2.1.1: DDC/War/Job/CompileDCE.hs
module DDC.War.Job.CompileDCE
( Spec (..)
, Result(..)
, resultSuccess
, build)
where
import BuildBox.Command.File
import BuildBox.Command.System
import BuildBox.Build.Benchmark
import BuildBox.Data.Physical
import BuildBox.IO.Directory
import BuildBox.Pretty
import BuildBox
import System.FilePath
import Control.Monad
import Data.List
-- | Use ddci-core to compile/make file a DCE file
data Spec
= Spec
{ -- | Root source file of the program (the 'Main.ds')
specFile :: FilePath
-- | Scratch dir to do the build in.
, specScratchDir :: String
-- | Put what DDC says to stdout here.
, specCompileStdout :: FilePath
-- | Put what DDC says to stderr here.
, specCompileStderr :: FilePath
-- | If Just, then we're making an executable, and put the binary here.
-- Otherwise simply compile it
, specMaybeMainBin :: Maybe FilePath
-- | True if the compile is expected to succeed, else not.
, specShouldSucceed :: Bool }
deriving Show
data Result
= ResultSuccess Seconds
| ResultUnexpectedFailure
| ResultUnexpectedSuccess
deriving Show
resultSuccess :: Result -> Bool
resultSuccess result
= case result of
ResultSuccess{} -> True
_ -> False
instance Pretty Result where
ppr result
= case result of
ResultSuccess seconds -> text "success" <+> parens (ppr seconds)
ResultUnexpectedFailure -> text "failed"
ResultUnexpectedSuccess -> text "unexpected"
-- Build ----------------------------------------------------------------------
-- | Compile a Disciple Core Sea source file.
build :: Spec -> Build Result
build (Spec srcDCE
buildDir mainCompOut mainCompErr
mMainBin shouldSucceed)
= do needs srcDCE
needs "bin/ddci-core"
-- The directory holding the Main.dce file.
let (srcDir, _srcFile) = splitFileName srcDCE
-- Touch the .dce files to the build directory to ensure they're built.
sources <- io
$ liftM (filter (\f -> isSuffixOf ".dce" f))
$ lsFilesIn srcDir
ssystemq $ "touch " ++ (intercalate " " sources)
-- ensure the output directory exists
ensureDir buildDir
-- Do the compile.
let compile
| Just mainBin <- mMainBin
= do -- If there is an existing binary then remove it.
ssystemq $ "rm -f " ++ mainBin
-- Build the program.
timeBuild
$ systemTee False
("bin/ddci-core"
++ " -set output " ++ mainBin
++ " -set outputdir " ++ buildDir
++ " -make " ++ srcDCE)
""
-- Compile the program.
| otherwise
= do timeBuild
$ systemTee False
("bin/ddci-core"
++ " -set outputdir " ++ buildDir
++ " -compile " ++ srcDCE)
""
(time, (code, strOut, strErr))
<- compile
atomicWriteFile mainCompOut strOut
atomicWriteFile mainCompErr strErr
case code of
ExitFailure _
| shouldSucceed -> return ResultUnexpectedFailure
ExitSuccess
| not shouldSucceed -> return ResultUnexpectedSuccess
_ -> return $ ResultSuccess time