-- | A module for useful utility functions for Shake build systems.moduleDevelopment.Shake.Util(parseMakefile ,needMakefileDependencies ,neededMakefileDependencies ,shakeArgsAccumulate ,shakeArgsPrune ,shakeArgsPruneWith ,)whereimportDevelopment.Shake importDevelopment.Shake.Internal.Rules.File importqualifiedData.ByteString.Char8asBSimportqualifiedGeneral.Makefile asBSimportData.Tuple.ExtraimportData.ListimportGeneral.GetOpt importData.IORefimportData.MaybeimportControl.Monad.ExtraimportSystem.IO.ExtraasIO-- | Given the text of a Makefile, extract the list of targets and dependencies. Assumes a-- small subset of Makefile syntax, mostly that generated by @gcc -MM@.---- > parseMakefile "a: b c\nd : e" == [("a",["b","c"]),("d",["e"])]parseMakefile::String->[(FilePath,[FilePath])]parseMakefile =map(BS.unpack***mapBS.unpack).BS.parseMakefile .BS.pack-- | Depend on the dependencies listed in a Makefile. Does not depend on the Makefile itself.---- > needMakefileDependencies file = need . concatMap snd . parseMakefile =<< liftIO (readFile file)needMakefileDependencies::FilePath->Action ()needMakefileDependencies file =needBS .concatMapsnd.BS.parseMakefile =<<liftIO(BS.readFilefile )-- | Depend on the dependencies listed in a Makefile. Does not depend on the Makefile itself.-- Use this function to indicate that you have /already/ used the files in question.---- > neededMakefileDependencies file = needed . concatMap snd . parseMakefile =<< liftIO (readFile file)neededMakefileDependencies::FilePath->Action ()neededMakefileDependencies file =neededBS .concatMapsnd.BS.parseMakefile =<<liftIO(BS.readFilefile )-- | Like `shakeArgsWith`, but instead of accumulating a list of flags, apply functions to a default value.-- Usually used to populate a record structure. As an example of a build system that can use either @gcc@ or @distcc@ for compiling:---- @-- import System.Console.GetOpt---- data Flags = Flags {distCC :: Bool} deriving Eq-- flags = [Option \"\" [\"distcc\"] (NoArg $ Right $ \\x -> x{distCC=True}) \"Run distributed.\"]---- main = 'shakeArgsAccumulate' 'shakeOptions' flags (Flags False) $ \\flags targets -> return $ Just $ do-- if null targets then 'want' [\"result.exe\"] else 'want' targets-- let compiler = if distCC flags then \"distcc\" else \"gcc\"-- \"*.o\" '%>' \\out -> do-- 'need' ...-- 'cmd' compiler ...-- ...-- @---- Now you can pass @--distcc@ to use the @distcc@ compiler.shakeArgsAccumulate::ShakeOptions ->[OptDescr(EitherString(a ->a ))]->a ->(a ->[String]->IO(Maybe(Rules ())))->IO()shakeArgsAccumulate opts flags def f =shakeArgsWith opts flags $\flags targets ->f (foldl'(flip($))def flags )targets -- | Like 'shakeArgs' but also takes a pruning function. If @--prune@ is passed, then after the build has completed,-- the second argument is called with a list of the files that the build checked were up-to-date.shakeArgsPrune::ShakeOptions ->([FilePath]->IO())->Rules ()->IO()shakeArgsPrune opts prune rules =shakeArgsPruneWith opts prune []f wheref _files =return$Just$ifnullfiles thenrules elsewant files >>withoutActions rules -- | A version of 'shakeArgsPrune' that also takes a list of extra options to use.shakeArgsPruneWith::ShakeOptions ->([FilePath]->IO())->[OptDescr(EitherStringa )]->([a ]->[String]->IO(Maybe(Rules ())))->IO()shakeArgsPruneWith opts prune flags act =doletflags2 =Option"P"["prune"](NoArg$RightNothing)"Remove stale files":map(fmapFmapOptDescr Just)flags pruning <-newIORefFalseshakeArgsWith opts flags2 $\opts args ->casesequenceopts ofNothing->dowriteIORefpruning TruereturnNothingJustopts ->act opts args whenM(readIORefpruning )$IO.withTempFile$\file ->doshakeArgsWith opts {shakeLiveFiles=file :shakeLiveFilesopts }flags2 $\opts args ->act (catMaybesopts )args src <-lines<$>IO.readFile'file prune src 

AltStyle によって変換されたページ (->オリジナル) /