module Development.Cake3 (
Variable
, Recipe
, RefInput(..)
, RefOutput(..)
, CakeString
, string
, A
, Make
, buildMake
, runMake
, runMakeH
, runMakeH_
, writeMake
, includeMakefile
, MonadMake(..)
, rule'
, rule
, phony
, depend
, produce
, ignoreDepends
, prebuild
, postbuild
, FileLike(..)
, FileT(..)
, File
, ModuleLocation(..)
, file'
, (.=)
, (</>)
, topRel
, readFileForMake
, genFile'
, genFile
, prerequisites
, shell
, unsafeShell
, cmd
, makevar
, extvar
, tool
, CommandGen'(..)
, make
, currentDirLocation
, gitSubmoduleFile
, module Data.String
, module Control.Monad
, module Control.Applicative
) where
import Control.Applicative
import Control.Monad
import Control.Monad.Trans
import Control.Monad.Writer
import Control.Monad.State
import Control.Monad.Loc
import Data.Char
import qualified Data.List as L
import Data.List (concat,map, (++), reverse,elem,intercalate,delete)
import Data.Foldable (Foldable(..), foldr)
import qualified Data.Map as M
import Data.Map (Map)
import qualified Data.Set as S
import Data.Set (Set,member,insert)
import Data.String
import Data.Tuple
import System.IO
import System.Directory
import qualified System.FilePath as F
import Text.Printf
import Development.Cake3.Types
import Development.Cake3.Writer
import Development.Cake3.Monad
import System.FilePath.Wrapper as W
currentDirLocation :: (MonadIO m) => m ModuleLocation
currentDirLocation = return toplevelModule
runMakeH
:: MakeState
-> (String -> IO b)
-> IO (MakeState,b)
runMakeH ms output = do
when (not $ L.null (warnings ms)) $ do
hPutStr stderr (warnings ms)
when (not $ L.null (errors ms)) $ do
fail (errors ms)
case buildMake ms of
Left e -> fail e
Right s -> do
o <- output s
return (ms,o)
runMakeH_
:: MakeState
-> (String -> IO b)
-> IO b
runMakeH_ ms h = snd `liftM` (runMakeH ms h)
runMake :: Make a -> IO String
runMake mk = do
ms <- evalMake defaultMakefile mk
runMakeH_ ms return
writeMake
:: File
-> Make a
-> IO ()
writeMake f mk = do
ms <- evalMake defaultMakefile mk
runMakeH_ ms (writeFile (topRel f))
withPlacement :: (MonadMake m) => m (Recipe,a) -> m (Recipe,a)
withPlacement mk = do
(r,a) <- mk
liftMake $ do
addPlacement 0 (S.findMin (rtgt r))
return (r,a)
rule' :: (MonadMake m)
=> A a
-> m (Recipe,a)
rule' act = liftMake $ do
loc <- getLoc
(r,a) <- runA loc act
addRecipe r
return (r,a)
rule
:: A a
-> Make a
rule act = snd `liftM` withPlacement (rule' act)
genFile' :: File -> String -> A () -> Make File
genFile' tgt cnt act =
rule $ do
case null cnt of
True -> do
shell [cmd| echo n > @tgt|]
False -> do
shell [cmd|( \|]
forM_ (lines cnt) $ \l -> do
shell [cmd|echo $(string (quote l)) ;\|]
shell [cmd|) > @tgt|]
act
return tgt
where
quote [] = []
quote ('$':cs) = '$':'$':(quote cs)
quote (x:cs)
| not (isAlphaNum x) = '\\':x:(quote cs)
| otherwise = x : (quote cs)
genFile :: File -> String -> Make File
genFile f c = genFile' f c (return ())
gitSubmoduleFile :: File -> Make File
gitSubmoduleFile file =
let
fm = (fileModule file)
dotgit = fm </> ".git"
in
rule $ do
depend $ do
rule $ do
when ((splitDirectories (topRel fm)) /= ["."]) $ do
shell [cmd| $(tool "git") C $fm submodule update
shell [cmd| $(tool "git") C $fm checkout f |]
return ()
shell [cmd| $(tool "touch") c @(dotgit)|]
shell [cmd| $(tool "touch") c @(file)|]
return file