{-# LANGUAGE CPP #-}
-- | This module is used for defining Shake build systems. As a simple example of a Shake build system,
-- let us build the file @result.tar@ from the files listed by @result.txt@:
--
-- @
--import "Development.Shake"
--import "Development.Shake.FilePath"
--
--main = 'shake' 'shakeOptions' $ do
-- 'want' [\"result.tar\"]
-- \"*.tar\" '*>' \\out -> do
-- contents <- 'readFileLines' $ 'Development.Shake.FilePath.replaceExtension' out \"txt\"
-- 'need' contents
-- 'system'' \"tar\" $ [\"-cf\",out] ++ contents
-- @
--
-- We start by importing the modules defining both Shake and routines for manipulating 'FilePath' values.
-- We define @main@ to call 'shake' with the default 'shakeOptions'. As the second argument to
-- 'shake', we provide a set of rules. There are two common forms of rules, 'want' to specify target files,
-- and '*>' to define a rule which builds a 'FilePattern'. We use 'want' to require that after the build
-- completes the file @result.tar@ should be ready.
--
-- The @*.tar@ rule describes how to build files with the extension @.tar@, including @result.tar@.
-- We 'readFileLines' on @result.txt@, after changing the @.tar@ extension to @.txt@. We read each line
-- into the variable @contents@ -- being a list of the files that should go into @result.tar@. Next, we
-- depend ('need') all the files in @contents@. If any of these files change, the rule will be repeated.
-- Finally we call the @tar@ program. If either @result.txt@ changes, or any of the files listed by @result.txt@
-- change, then @result.tar@ will be rebuilt.
--
-- When writing a Shake build system, start by defining what you 'want', then write rules
-- with '*>' to produce the results. Before calling 'system'' you should ensure that any files the command
-- requires are demanded with calls to 'need'. We offer the following advice to Shake users:
--
-- * If @ghc --make@ or @cabal@ is capable of building your project, use that instead. Custom build systems are
-- necessary for many complex projects, but many projects are not complex.
--
-- * The CmdArgs package () is well suited to providing
-- command line parsing for build systems, often using flags to set fields in 'shakeOptions'.
--
-- * Put all result files in a distinguished directory, for example @_make@. You can implement a @clean@
-- command by removing that directory, using 'removeDirectoryRecursive'.
--
-- * To obtain parallel builds set 'shakeThreads' to a number greater than 1. You may also need to
-- compile with @-threaded@.
--
-- * Often the 'want' commands will be determined by command line arguments, to mirror the behaviour of @make@
-- targets. For a default set of 'want' commands that you later override, 'withoutActions' can be useful.
--
-- * Lots of compilers produce @.o@ files. To avoid overlapping rules, use @.c.o@ for C compilers,
-- @.hs.o@ for Haskell compilers etc.
--
-- * Do not be afraid to mix Shake rules, system commands and other Haskell libraries -- use each for what
-- it does best.
--
-- * The more accurate the dependencies are, the better. Use additional rules like 'doesFileExist' and
-- 'getDirectoryFiles' to track information other than just the contents of files. For information in the environment
-- that you suspect will change regularly (perhaps @ghc@ version number), either write the information to
-- a file with 'alwaysRerun' and 'writeFileChanged', or use 'addOracle'.
--
-- The theory behind Shake is described in an ICFP 2012 paper, Shake Before Building -- Replacing Make with Haskell
-- . The associated talk
-- forms a short overview of Shake .
--
-- /Acknowledgements/: Thanks to Austin Seipp for properly integrating the profiling code.
module Development.Shake(
shake,
-- * Core of Shake
ShakeOptions(..), shakeOptions, Assume(..), Progress(..),
#if __GLASGOW_HASKELL__ >= 704
ShakeValue,
#endif
Rule(..), Rules, defaultRule, rule, action, withoutActions,
Action, apply, apply1, traced,
Verbosity(..), getVerbosity, putLoud, putNormal, putQuiet,
liftIO,
-- * Utility functions
module Development.Shake.Derived,
-- * File rules
need, want, (*>), (**>), (?>),
module Development.Shake.Files,
FilePattern, (?==),
-- * Directory rules
doesFileExist, getDirectoryContents, getDirectoryFiles, getDirectoryDirs,
-- * Additional rules
addOracle, askOracle, askOracleWith,
alwaysRerun,
-- * Finite resources
Resource, newResource, withResource
) where
-- I would love to use module export in the above export list, but alas Haddock
-- then shows all the things that are hidden in the docs, which is terrible.
import Control.Monad.IO.Class
import Development.Shake.Types
import Development.Shake.Core
import Development.Shake.Derived
#if __GLASGOW_HASKELL__ >= 704
import Development.Shake.Classes
#endif
import Development.Shake.Directory
import Development.Shake.File
import Development.Shake.FilePattern
import Development.Shake.Files
import Development.Shake.Oracle
import Development.Shake.Rerun
-- | Main entry point for running Shake build systems. For an example see the top of the module "Development.Shake".
-- Use 'ShakeOptions' to specify how the system runs, and 'Rules' to specify what to build.
shake :: ShakeOptions -> Rules () -> IO ()
shake opts r = do
run opts $ do
r
defaultRuleFile
defaultRuleDirectory
defaultRuleRerun
return ()