-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Third cake the Makefile EDSL -- -- Cake3 is a EDSL for building Makefiles, written in Haskell. With -- cake3, developer can write their build logic in Haskell, obtain clean -- and safe Makefile and distribute it among the non-Haskell-aware users. -- Currenly, GNU Make is the only backend supported. -- -- Example program -- --
-- module Cakefile where -- -- import Development.Cake3 -- import Cakefile_P -- -- cs = map file ["main.c", "second.c"] -- -- main = writeMake (file "Makefile") $ do -- selfUpdate -- d <- rule $ do -- shell [cmd|gcc -M $cs -MF @(file "depend.mk")|] -- os <- forM cs $ \c -> do -- rule $ do -- shell [cmd| gcc -c $(extvar "CFLAGS") -o @(c.="o") $c |] -- elf <- rule $ do -- shell [cmd| gcc -o @(file "main.elf") $os |] -- rule $ do -- phony "all" -- depend elf -- includeMakefile d ---- -- Basic workflow -- --
-- rule $ do -- phony "clean" -- unsafeShell [cmd|rm $elf $os $d|] --phony :: Monad m => String -> A' m () -- | Mark the recipe as INTERMEDIATE i.e. claim that all it's -- targets may be removed after the build process. Makefile-specific. markIntermediate :: Monad m => A' m () -- | Obtain the contents of a File. Note, that this generally means, that -- Makefile should be regenerated each time the File is changed. readFileForMake :: MonadMake m => File -> m ByteString -- | CommandGen is a recipe-builder packed in the newtype to prevent -- partial expantion of it's commands newtype CommandGen' m CommandGen' :: A' m Command -> CommandGen' m unCommand :: CommandGen' m -> A' m Command type CommandGen = CommandGen' (Make' IO) -- | Pack the command builder into a CommandGen commandGen :: A Command -> CommandGen -- | Modifie the recipe builder: ignore all the dependencies ignoreDepends :: Monad m => A' m a -> A' m a -- | Apply the recipe builder to the current recipe state. Return the list -- of targets of the current Recipe under construction shell :: Monad m => CommandGen' m -> A' m [File] -- | Version of shell which doesn't track it's dependencies unsafeShell :: Monad m => CommandGen' m -> A' m [File] -- | Simple wrapper for strings, a target for various typeclass instances. newtype CakeString CakeString :: String -> CakeString -- | An alias to CakeString constructor string :: String -> CakeString -- | Class of things which may be referenced using '@(expr)' syntax of the -- quasi-quoted shell expressions. class Monad m => RefOutput m x refOutput :: RefOutput m x => x -> A' m Command inbetween :: Monad m => t -> m [[t]] -> m [t] spacify :: Monad m => m [[CommandPiece]] -> m [CommandPiece] -- | Class of things which may be referenced using '$(expr)' syntax of the -- quasy-quoted shell expressions class MonadAction a m => RefInput a m x refInput :: RefInput a m x => x -> a Command -- | Add it's argument to the list of dependencies (prerequsites) of a -- current recipe under construction depend :: RefInput a m x => x -> a () -- | Declare that current recipe produces some producable item. produce :: RefOutput m x => x -> A' m () -- | Add variables vs to tracking list of the current recipe variables :: (Foldable t, Monad m) => (t Variable) -> A' m () -- | Add tools ts to the tracking list of the current recipe tools :: (Foldable t, Monad m) => (t Tool) -> A' m () -- | Add commands to the list of commands of a current recipe under -- construction. Warning: this function behaves like unsafeShell i.e. it -- doesn't analyze the command text commands :: Monad m => [Command] -> A' m () -- | Set the recipe's location in the Cakefile.hs location :: Monad m => String -> A' m () -- | Set additional flags flags :: Monad m => Set Flag -> A' m () -- | Has effect of a function QQ -> CommandGen where QQ is a -- string supporting the following syntax: -- --
-- [cmd|gcc $flags -o @file|] ---- -- is equivalent to -- --
-- return $ CommandGen $ do -- s1 <- refInput "gcc " -- s2 <- refInput (flags :: Variable) -- s3 <- refInput " -o " -- s4 <- refOutput (file :: File) -- return (s1 ++ s2 ++ s3 ++ s4) ---- -- Later, this command may be examined or passed to the shell function to -- apply it to the recipe cmd :: QuasiQuoter instance [overlap ok] Monad m => Monad (Make' m) instance [overlap ok] Functor m => Functor (Make' m) instance [overlap ok] (Monad m, Functor m) => Applicative (Make' m) instance [overlap ok] Monad m => MonadState MakeState (Make' m) instance [overlap ok] MonadIO m => MonadIO (Make' m) instance [overlap ok] MonadFix m => MonadFix (Make' m) instance [overlap ok] Monad m => Monad (A' m) instance [overlap ok] Functor m => Functor (A' m) instance [overlap ok] (Monad m, Functor m) => Applicative (A' m) instance [overlap ok] Monad m => MonadState Recipe (A' m) instance [overlap ok] MonadIO m => MonadIO (A' m) instance [overlap ok] MonadFix m => MonadFix (A' m) instance [overlap ok] Show CakeString instance [overlap ok] Eq CakeString instance [overlap ok] Ord CakeString instance [overlap ok] MonadAction a m => RefInput a m (CommandGen' m) instance [overlap ok] MonadAction a m => RefInput a m CakeString instance [overlap ok] MonadAction a m => RefInput a m Tool instance [overlap ok] MonadAction a m => RefInput a m Variable instance [overlap ok] RefInput a m x => RefInput a m (Maybe x) instance [overlap ok] (RefInput a m x, MonadMake a) => RefInput a m (Make x) instance [overlap ok] (MonadAction a m, MonadMake a) => RefInput a m (Make Recipe) instance [overlap ok] (MonadIO a, RefInput a m x) => RefInput a m (IO x) instance [overlap ok] MonadAction a m => RefInput a m (Set File) instance [overlap ok] RefInput a m x => RefInput a m [x] instance [overlap ok] MonadAction a m => RefInput a m Recipe instance [overlap ok] MonadAction a m => RefInput a m File instance [overlap ok] RefOutput m x => RefOutput m (Maybe x) instance [overlap ok] Monad m => RefOutput m (Set File) instance [overlap ok] Monad m => RefOutput m [File] instance [overlap ok] Monad m => RefOutput m File instance [overlap ok] Monad m => MonadAction (A' m) m instance [overlap ok] Monad m => MonadLoc (Make' m) instance [overlap ok] MonadMake m => MonadMake (StateT s m) instance [overlap ok] MonadMake m => MonadMake (A' m) instance [overlap ok] MonadMake (Make' IO) module Development.Cake3.Writer -- | Default Makefile location defaultMakefile :: File -- | Render the Makefile. Return either the content (Right), or error -- messages (Left). buildMake :: MakeState -> Either String String instance Functor MakeLL instance Monad MakeLL instance MonadState ([File], Set Recipe) MakeLL instance Applicative MakeLL instance ToMakeText (Set File) instance ToMakeText CommandPiece instance ToMakeText Command instance ToMakeText File instance ToMakeText [Char] module Development.Cake3 -- | The representation of Makefile variable. data Variable -- | Recipe answers to the question 'How to build the targets'. Internally, -- it contains sets of targets and prerequisites, as well as shell -- commands required to build former from latter data Recipe -- | Class of things which may be referenced using '$(expr)' syntax of the -- quasy-quoted shell expressions class MonadAction a m => RefInput a m x refInput :: RefInput a m x => x -> a Command -- | Class of things which may be referenced using '@(expr)' syntax of the -- quasi-quoted shell expressions. class Monad m => RefOutput m x refOutput :: RefOutput m x => x -> A' m Command -- | Simple wrapper for strings, a target for various typeclass instances. data CakeString -- | An alias to CakeString constructor string :: String -> CakeString -- | Verison of Action monad with fixed parents type A a = A' (Make' IO) a type Make a = Make' IO a -- | Render the Makefile. Return either the content (Right), or error -- messages (Left). buildMake :: MakeState -> Either String String -- | Execute the mk monad, return the Makefile as a String. In -- case of errors, print report to stderr and abort the execution with -- fail call runMake :: Make a -> IO String -- | A Generic Make monad runner. Execute the monad mk, provide -- the output handler with Makefile encoded as a string. Note -- that Makefile may contain rules which references the file itself by -- the name makefile. In case of errors, print report to stderr -- and abort the execution with fail call runMakeH :: MakeState -> (String -> IO b) -> IO (MakeState, b) -- | A Version of runMakeH returning no state runMakeH_ :: MakeState -> (String -> IO b) -> IO b -- | Execute the mk monad, build the Makefile, write it to the -- output file. In case of errors, print report to stderr and abort the -- execution with fail call writeMake :: File -> Make a -> IO () -- | Add 'include ...' directive to the final Makefile for each input file. includeMakefile :: Foldable t => t File -> Make () -- | A Monad providing access to MakeState. TODO: not mention IO here. class Monad m => MonadMake m liftMake :: MonadMake m => (Make' IO) a -> m a -- | A version of rule2. Rule places it's recipe above all recipies defined -- so far. rule :: A a -> Make a -- | Build a Recipe using the builder provided and record it to the -- MakeState. Return the copy of Recipe (which should not be changed in -- future) and the result of recipe builder. The typical recipe builder -- result is the list of it's targets. -- -- Example Lets declare a rule which builds "main.o" out of -- "main.c" and CFLAGS variable -- --
-- let c = file "main.c" -- rule $ shell [cmd| gcc -c $(extvar "CFLAGS") -o @(c.="o") $c |] --rule2 :: MonadMake m => A a -> m (Recipe, a) -- | A version of rule, without monad set explicitly rule' :: MonadMake m => A a -> m a -- | Adds the phony target for a rule. Typical usage: -- --
-- rule $ do -- phony "clean" -- unsafeShell [cmd|rm $elf $os $d|] --phony :: Monad m => String -> A' m () -- | Add it's argument to the list of dependencies (prerequsites) of a -- current recipe under construction depend :: RefInput a m x => x -> a () -- | Declare that current recipe produces some producable item. produce :: RefOutput m x => x -> A' m () -- | Modifie the recipe builder: ignore all the dependencies ignoreDepends :: Monad m => A' m a -> A' m a -- | Add prebuild command prebuild :: MonadMake m => CommandGen -> m () -- | Add prebuild command postbuild :: MonadMake m => CommandGen -> m () class FileLike a combine :: FileLike a => a -> String -> a takeDirectory :: FileLike a => a -> a takeBaseName :: FileLike a => a -> String takeFileName :: FileLike a => a -> String makeRelative :: FileLike a => a -> a -> a replaceExtension :: FileLike a => a -> String -> a takeExtension :: FileLike a => a -> String takeExtensions :: FileLike a => a -> String dropExtensions :: FileLike a => a -> a dropExtension :: FileLike a => a -> a splitDirectories :: FileLike a => a -> [String] -- | Simple wrapper for FilePath. type File = FileT FilePath -- | Converts string representation of Path into type-safe File. -- Internally, files are stored as a relative offsets from the project -- root directory file' :: ProjectLocation -> String -> File -- | Alias for replaceExtension (.=) :: FileLike a => a -> String -> a -- | Redefine standard / operator to work with Files (>) :: FileLike a => a -> String -> a -- | Convert File back to FilePath toFilePath :: (FileT FilePath) -> FilePath -- | Obtain the contents of a File. Note, that this generally means, that -- Makefile should be regenerated each time the File is changed. readFileForMake :: MonadMake m => File -> m ByteString genFile :: MonadMake m => File -> String -> m File -- | Get a list of prerequisites added so far prerequisites :: (Applicative m, Monad m) => A' m (Set File) -- | Apply the recipe builder to the current recipe state. Return the list -- of targets of the current Recipe under construction shell :: Monad m => CommandGen' m -> A' m [File] -- | Version of shell which doesn't track it's dependencies unsafeShell :: Monad m => CommandGen' m -> A' m [File] -- | Has effect of a function QQ -> CommandGen where QQ is a -- string supporting the following syntax: -- --
-- [cmd|gcc $flags -o @file|] ---- -- is equivalent to -- --
-- return $ CommandGen $ do -- s1 <- refInput "gcc " -- s2 <- refInput (flags :: Variable) -- s3 <- refInput " -o " -- s4 <- refOutput (file :: File) -- return (s1 ++ s2 ++ s3 ++ s4) ---- -- Later, this command may be examined or passed to the shell function to -- apply it to the recipe cmd :: QuasiQuoter -- | Define the Makefile-level variable. Rules, referring to a variable, -- notice it's changes. makevar :: String -> String -> Variable -- | Declare the variable defined elsewhere. Typycally, environment -- variables may be decalred with this functions. Variables are tracked -- by the cake3. Rules, referring to a variable, notice it's -- changes. extvar :: String -> Variable tool :: String -> Tool -- | CommandGen is a recipe-builder packed in the newtype to prevent -- partial expantion of it's commands newtype CommandGen' m CommandGen' :: A' m Command -> CommandGen' m unCommand :: CommandGen' m -> A' m Command -- | Reref to special variable $(MAKE) make :: Variable data ProjectLocation ProjectLocation :: FilePath -> FilePath -> ProjectLocation root :: ProjectLocation -> FilePath off :: ProjectLocation -> FilePath currentDirLocation :: MonadIO m => m ProjectLocation instance Show ProjectLocation instance Eq ProjectLocation instance Ord ProjectLocation module Development.Cake3.Ext.UrWeb data UrpAllow UrpMime :: UrpAllow UrpUrl :: UrpAllow UrpResponseHeader :: UrpAllow UrpEnvVar :: UrpAllow UrpHeader :: UrpAllow data UrpRewrite UrpStyle :: UrpRewrite UrpAll :: UrpRewrite UrpTable :: UrpRewrite data UrpHdrToken UrpDatabase :: String -> UrpHdrToken UrpSql :: File -> UrpHdrToken UrpAllow :: UrpAllow -> String -> UrpHdrToken UrpRewrite :: UrpRewrite -> String -> UrpHdrToken UrpLibrary :: File -> UrpHdrToken UrpDebug :: UrpHdrToken UrpInclude :: File -> UrpHdrToken UrpLink :: (Either File String) -> UrpHdrToken UrpSrc :: File -> String -> String -> UrpHdrToken UrpPkgConfig :: String -> UrpHdrToken UrpFFI :: File -> UrpHdrToken -- | Module name, UrWeb name, JavaScript name UrpJSFunc :: String -> String -> String -> UrpHdrToken UrpSafeGet :: String -> UrpHdrToken UrpScript :: String -> UrpHdrToken UrpClientOnly :: String -> UrpHdrToken data UrpModToken UrpModule1 :: File -> UrpModToken UrpModule2 :: File -> File -> UrpModToken UrpModuleSys :: String -> UrpModToken data Urp Urp :: File -> Maybe File -> [UrpHdrToken] -> [UrpModToken] -> Urp urp :: Urp -> File uexe :: Urp -> Maybe File uhdr :: Urp -> [UrpHdrToken] umod :: Urp -> [UrpModToken] newtype UWLib UWLib :: Urp -> UWLib newtype UWExe UWExe :: Urp -> UWExe class UrpLike x where tempfiles = (\ x -> (urpObjs x) ++ maybeToList (urpSql' x) ++ maybeToList (urpExe' x)) . toUrp toUrp :: UrpLike x => x -> Urp tempfiles :: UrpLike x => x -> [File] urpDeps :: Urp -> [File] urpSql' :: Urp -> Maybe File urpSql :: Urp -> File urpSrcs :: Urp -> [(File, String)] urpObjs :: Urp -> [File] urpLibs :: Urp -> [File] urpExe' :: Urp -> Maybe File urpExe :: Urp -> File urpPkgCfg :: Urp -> [String] data UrpState UrpState :: Urp -> File -> UrpState urpst :: UrpState -> Urp urautogen :: UrpState -> File defState :: File -> UrpState class ToUrpWord a toUrpWord :: ToUrpWord a => a -> String class ToUrpLine a toUrpLine :: ToUrpLine a => FilePath -> a -> String maskPkgCfg :: [Char] -> [Char] newtype UrpGen m a UrpGen :: StateT UrpState m a -> UrpGen m a unUrpGen :: UrpGen m a -> StateT UrpState m a toFile :: MonadIO m => FileT FilePath -> Writer String a -> m () tempPrefix :: File -> String mkFileRule :: MonadMake m => String -> Writer String a -> m File line :: MonadWriter String m => String -> m () uwlib :: File -> UrpGen (Make' IO) () -> Make UWLib uwapp :: String -> File -> UrpGen (Make' IO) () -> Make UWExe setAutogenDir :: MonadState UrpState m => File -> m () addHdr :: MonadState UrpState m => UrpHdrToken -> m () addMod :: MonadState UrpState m => UrpModToken -> m () database :: MonadMake m => String -> UrpGen m () allow :: MonadMake m => UrpAllow -> String -> UrpGen m () rewrite :: MonadMake m => UrpRewrite -> String -> UrpGen m () urpUp :: File -> FilePath -- | A general method of including a library into the UrWeb project. library' :: MonadMake m => Make [File] -> UrpGen m () -- | Include a library defined somewhere in the current project library :: MonadMake m => UWLib -> UrpGen m () -- | Build a file using external Makefile facility. externalMake3 :: File -> File -> String -> Make [File] -- | Build a file using external Makefile facility. externalMake' :: File -> File -> Make [File] -- | Build a file from external project. It is expected, that this project -- has a Makwfile in it's root directory. Call Makefile with the -- default target externalMake :: File -> Make [File] -- | Build a file from external project. It is expected, that this project -- has a Makwfile in it's root directory externalMakeTarget :: File -> String -> Make [File] -- | Build a file from external project. It is expected, that this project -- has a fiel.mk (a Makefile with an unusual name) in it's root directory externalMake2 :: File -> Make [File] ur :: MonadMake m => UrpModToken -> UrpGen m () module_ :: MonadMake m => UrpModToken -> UrpGen m () pair :: File -> UrpModToken single :: File -> UrpModToken sys :: String -> UrpModToken debug :: MonadMake m => UrpGen m () include :: MonadMake m => File -> UrpGen m () link' :: MonadMake m => File -> String -> UrpGen m () link :: MonadMake m => File -> UrpGen m () csrc' :: MonadMake m => File -> String -> String -> UrpGen m () csrc :: MonadMake m => File -> UrpGen m () ffi :: MonadMake m => File -> UrpGen m () sql :: MonadMake m => File -> UrpGen m () jsFunc :: MonadState UrpState m => String -> String -> String -> m () safeGet' :: MonadMake m => String -> UrpGen m () safeGet :: MonadMake m => File -> String -> UrpGen m () url :: UrpAllow mime :: UrpAllow style :: UrpRewrite all :: UrpRewrite table :: UrpRewrite env :: UrpAllow hdr :: UrpAllow requestHeader :: UrpAllow responseHeader :: UrpAllow script :: MonadMake m => String -> UrpGen m () guessMime :: String -> [Char] pkgconfig :: MonadMake m => String -> UrpGen m () type BinOptions = [BinOption] data BinOption NoScan :: BinOption UseUrembed :: BinOption bin :: (MonadIO m, MonadMake m) => File -> BinOptions -> UrpGen m () bin' :: (MonadIO m, MonadMake m) => FilePath -> ByteString -> BinOptions -> UrpGen m () data JSFunc JSFunc :: String -> String -> String -> JSFunc -- | URS declaration for this function urdecl :: JSFunc -> String -- | UrWeb name of this function urname :: JSFunc -> String -- | JavaScript name of this function jsname :: JSFunc -> String data JSType JSType :: String -> JSType urtdecl :: JSType -> String -- | Parse the JavaScript file, extract top-level functions, convert their -- signatures into Ur/Web format, return them as the list of strings parse_js :: ByteString -> Make (Either String ([JSType], [JSFunc])) transform_css :: Stream s m Char => ParsecT s u m [Either ByteString [Char]] parse_css :: Monad m => ByteString -> (String -> m String) -> m (Either ParseError ByteString) instance Typeable UrpAllow instance Typeable UrpRewrite instance Typeable UrpHdrToken instance Typeable UrpModToken instance Typeable Urp instance Typeable UWLib instance Typeable UWExe instance Show UrpAllow instance Data UrpAllow instance Show UrpRewrite instance Data UrpRewrite instance Show UrpHdrToken instance Data UrpHdrToken instance Show UrpModToken instance Data UrpModToken instance Show Urp instance Data Urp instance Show UWLib instance Data UWLib instance Show UWExe instance Data UWExe instance Show UrpState instance Functor m => Functor (UrpGen m) instance (Monad m, Functor m) => Applicative (UrpGen m) instance Monad m => Monad (UrpGen m) instance Monad m => MonadState UrpState (UrpGen m) instance MonadMake m => MonadMake (UrpGen m) instance MonadIO m => MonadIO (UrpGen m) instance Show BinOption instance Eq BinOption instance Show JSFunc instance Show JSType instance ToUrpLine UrpModToken instance ToUrpLine UrpHdrToken instance ToUrpWord UrpRewrite instance ToUrpWord UrpAllow instance UrpLike UWExe instance UrpLike UWLib instance UrpLike Urp instance MonadAction a m => RefInput a m UWExe instance MonadAction a m => RefInput a m UWLib module Development.Cake3.Utils.Find filterExts :: [String] -> [File] -> [File] getDirectoryContentsRecursive :: MonadIO m => File -> m [File] module Development.Cake3.Utils.Slice -- | Build the full Makefile named fo and a set of sliced -- versions. Slicing here means filtering out all rules which -- depends on certain tools (second element of sls) and all -- upstream rules. writeSliced :: File -> [(File, [Tool])] -> Make a -> IO ()