module Development.Cake3 (
Variable
, Recipe
, RefInput(..)
, RefOutput(..)
, CakeString
, string
, A
, Make
, buildMake
, runMake
, writeMake
, includeMakefile
, MonadMake(..)
, rule
, rule2
, rule'
, phony
, depend
, produce
, ignoreDepends
, prebuild
, postbuild
, FileLike(..)
, File
, file'
, (.=)
, (</>)
, toFilePath
, readFileForMake
, prerequisites
, shell
, unsafeShell
, cmd
, makevar
, extvar
, CommandGen'(..)
, make
, ProjectLocation(..)
, currentDirLocation
, 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 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
data ProjectLocation = ProjectLocation {
root :: FilePath
, off :: FilePath
} deriving (Show, Eq, Ord)
currentDirLocation :: (MonadIO m) => m ProjectLocation
currentDirLocation = do
cwd <- liftIO $ getCurrentDirectory
return $ ProjectLocation cwd cwd
file' :: ProjectLocation -> String -> File
file' pl f' = fromFilePath (addpoint (F.normalise rel)) where
rel = makeRelative (root pl) ((off pl) </> f)
f = F.dropTrailingPathSeparator f'
addpoint "." = "."
addpoint p = "."</>p
runMake'
:: File
-> Make a
-> (String -> IO b)
-> IO b
runMake' makefile mk output = do
ms <- evalMake makefile mk
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 -> output s
writeMake
:: File
-> Make a
-> IO ()
writeMake f mk = runMake' f mk (writeFile (toFilePath f))
runMake :: Make a -> IO String
runMake mk = runMake' defaultMakefile mk return
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)
phony ::
String
-> A ()
phony name = do
produce (W.fromFilePath name :: File)
markPhony
rule2 :: (MonadMake m)
=> A a
-> m (Recipe,a)
rule2 act = liftMake $ do
loc <- getLoc
(r,a) <- runA loc act
addRecipe r
return (r,a)
rule
:: A a
-> Make a
rule act = snd <$> withPlacement (rule2 act)
rule' :: (MonadMake m) => A a -> m a
rule' act = liftMake $ snd <$> withPlacement (rule2 act)