Build system library, like Make, but more accurate dependencies.

Version on this page:0.15.2@rev:1
LTS Haskell 22.30:0.19.8
Stackage Nightly 2024-07-24:0.19.8
Latest on Hackage:0.19.8

See all snapshots shake appears in

BSD-3-Clause licensed and maintained by Neil Mitchell
This version can be pinned in stack with:shake-0.15.2@sha256:06a507e0523ae0f9c2b9a663732b9f0a758c584d51027692fb9dbd305b70d936,8240

Shake Hackage version Build Status

Shake is a tool for writing build systems - an alternative to make, Scons, Ant etc. Shake has been used commercially for over five years, running thousands of builds per day. The website for Shake users is at


  • Why use Shake? Shake lets you write large robust build systems, which deal properly with generated source files and run quickly. If you are writing a custom build system of any moderate size (more than a few rules) you should use Shake. The advantages over other build systems are detailed in the document Why choose Shake?.
  • How do I use Shake? Shake is a Haskell library that you use to define your rules. The Shake manual provides a walk through of a small but realistic example, assuming no Haskell knowledge.
  • Generated documentation for all functions, includes lots of examples.
  • Running Ninja builds using Shake.
  • Blog posts detailing ongoing development work.
  • Profile report demo explaining what the profile reports mean.
  • Academic paper on the underlying principles behind Shake.
  • Video of a talk introducing Shake.

Other links

  • Download the Haskell package from Hackage and install it using Cabal.
  • Mailing list for any questions/bugs/thoughts on Shake. If you need more information and aren’t sure where to start, use the mailing list.
  • Questions can be asked on StackOverflow with the tag shake-build-system.
  • Bugs can be reported on the GitHub issue tracker.
  • Source code in a git repo, stored at GitHub.
  • Continuous integration with Travis and Hydra.

Is your company using Shake? Write something public (even just a tweet to @ndm_haskell) and I’ll include a link at on the website.


Changelog for Shake

#248, add another example of using cmd
#245, initial support for fsatrace lint checking
Reexport -<.> from filepath where available
Hoogle #106, trigger on filepath version, not GHC version
Add AddEnv and AddPath command options
#243, close fds in child processes when spawning commands
Make Ninja variable handling more accurate
If you have Shakefile.hs, pass it all arguments without interp
Add shakeArgsPrune and shakeArgsPruneWith
#228, allow running cmd async by collecting the ProcessHandle
Make getShakeOptions/processorCount of 0 return the used value
#212, document how to get a full terminal with cmd
#225, warn if there are no want/action statements
#232, don't ignore phony order-only dependencies in Ninja
#226, add escaping for GraphViz labels
#227, add StdinBS for passing a bytestring as Stdin
Make cmd Timeout call terminateProcess as well
#203, make shakeFiles a directory rather than a file prefix
#220, add getHashedShakeVersion helper
#220, add shakeVersionIgnore to ignore version numbers
#219, run Shakefile.hs from the shake binary
#218, fix issues with incorrect unchanging with no digests
#218, fix issue with ChangeModtimeAndDigest on unchanging files
#216, work around GHC 7.10 RC3 bug 10176
#213, add phonys, a predicate phony rule
Add CmdTime and CmdLine results to cmd/command
Fix parseMakefile for words with multiple escapes in them
#205, add WithStdout, like WithStderr
#27, add support for capturing Stdout/Stderr with bytestrings
Add FileStdout/FileStderr to write a stream direct to a file
#211, add Stdouterr to capture both Stdout and Stderr streams
Require extra-1.1 (to use nubOrd)
Generalise cmd to work with Maybe [String]
Add unit for use with cmd
IMPORTANT: Incompatible on disk format change
#209, improve orderOnly dependencies
Support for the filepath shipped with GHC 7.10
Add Timeout option to command
#198, add <//> operator to join FilePatterns
#198, fix the <.> and other extension methods to work with //
#196, change the links to point at
Improve the error messages when &%> or &?> go wrong
Normalise file patterns used by &?>
Make FilePattern on Windows cope with all path separators
Rename normalise to normaliseEx
Expose native System.FilePath in Development.Shake.FilePath
#193, eliminate the custom version of </>
#193, make need/orderOnly call normalise on their arguments
#177, use the $PATH variable to resolve cmd
#182, use js-jquery and js-flot
#195, add getConfigKeys
#194, replace *> with %> as the operator for rules
#188, improve the docs on FilePattern
#187, removeFiles on a missing directory should do nothing
#166, add withTempFile and withTempDir in the Action monad
Ensure Ninja response files are always deleted
Fix incorrect units when showing profile to the console
Require the extra library
#178, make --help show the current executable name
#171, fix the --demo mode on Linux
Ensure you wait until the progress thread cleans up
Add --demo mode
Add --progress=record and --progress=replay
Add -j to run with one thread per processor
Fix progress reporting to work even on the first run
Apply abbreviations to staunch failure messages
Fix failure progress messages during staunch mode
#165, make |*> matching with simple files much faster
Add toStandard to the FilePath module
#130, support msvc_deps_prefix in Ninja
#157, allow variable substitution in include/subninja statements
#147, add the version in the profile reports
#147, add --numeric-version flag
#28, switch to continuation passing style, uses far less threads
#156, add readConfigFileWithEnv for configs with an initial env
#129, fix processor count detection on Mac with -threaded
#155, add --live and shakeLiveFiles
#153, handle escaped spaces in parseMakefile
#152, fix typo in the manual
Add copyFileChanged
Fix the leaf column in profile reports
Add Maybe instances for cmd arguments
Add a --profile flag (alias for --report)
Switch to an underlying continuation monad
#95, ensure progress never gets corrupted
#124, add a profile report demo
#128, allow long Ninja command lines
Fix --report=- for builds with no commands in them
Remove all package upper bounds
#126, Ninja compatibility if Ninja fails to create a file
#123, generate Chrome compatible traces
#122, make --report=- write a report to stdout
Improve the profile report summary
#122, turn shakeReport into a list of files, instead of a Maybe
#60, improve how command lines are printed out
#113, print info about copyFile' and removeFilesAfter at -V
Replace **> with |*> , ?>> with &?> and *>> with &*>
IMPORTANT: Incompatible on disk format change
#83, support digest rules for files
#83, add shakeChange parameter and --digest* args
#83, add equalValue function to Rule typeclass
Deprecate defaultRule
Make literal *> matches take precedence over wildcard matches
#120, add a priority function
#62, move to a ReaderT/IORef for the Action monad
Add DEPRECATED pragmas on system' calls
Delete Development.Shake.Sys, use command or cmd instead
Add a 'console' pool to Ninja
Avoid using System.Cmd (deprecated in GHC HEAD)
#41, use higher precision file times on POSIX
#117, use higher precision times for Unicode files on Windows
#118, add support for Ninja -t compdb
#119, more test fixes for Linux GHC 7.8
#119, test fixes for Linux GHC 7.8
#114, run in the test suite with sh
#115, fix the test suite on Linux GHC 7.8
#116, fix for GHC 7.10
Include the sources for flot and jQuery in the dist tarball
Note that .. in FilePattern values is unlikely to be correct
#109, make removeFiles delete directories that match
#84, make removeFiles not delete empty unmatched directories
#111, fixes to the user manual
#110, don't give a warning if -threaded is turned off
#103, don't suggest -qg and -qb, they fail without -threaded
#102, fix up </> when the LHS starts with .
Work with QuickCheck-2.7 (which defines ===)
#100, handle GraphViz missing gracefully
Fix up the profiling report generation
#99, add getEnvWithDefault
#97, fix a serialisation bug when > 254 arguments to need
#96, fix a bug in addPath that caused $PATH to be added twice
#94, GHC 7.8 support
Add a Config module
#89, support :: as a build rule separator
Add alternatives to allow overlapping rules
Make storedValue take a ShakeOptions structure
Generalise the newCache function
Improve the performance of the Ninja parser
Make the database more compact
#84, ensure you normalise removeFile patterns first
#82, make -j0 guess at the number of processors
#81, add --lint-tracker to use tracker.exe
Add trackRead, trackWrite
Add trackUse, trackChange, trackAllow
#85, move rule creation functions into Development.Shake.Rule
Mark Development.Shake.Sys as DEPRECATED with a pragma
Change shakeLint to be of type Maybe Lint, instead of Bool
#50, add shakeArgsAccumulate
Improve Ninja --lint checking
#76, add Ninja specific lint checking
#75, add orderOnly dependencies
#76, add needed, to assert a need doesn't rebuild
#78, don't use cabal in the test suite
#77, add shakeRunCommands and --skip-commands
#67, add withVerbosity
#51, add getShakeOptions
Lots of Haddock improvements
Deprecate system', use cmd or command instead
#53, add addPath and addEnv to modify environment variables
Make all search path things return the native separators
#73, if Haskell can't write a unicode filename, skip the test
Print out the entire database in diagnostics mode
Rewrite database writes, old code could break metadata on error
#25, optimise building with Ninja
Fix many bugs in FilePath.normalise
Require QuickCheck-2.0 or higher
Change how the makefile parser treats \ characters
Add a --no-build flag
#74, allow cmd to be used with result IO
Add a Util module, with Makefile parsing
Allow unix-1.5.1 again
Require Cabal 1.10 or above
Convert to the cabal test compatible test suite
Support time-1.2
#71, fix a bug when requesting all three outputs from command
#64, add progressProgram and use it in progressSimple
Remove isRunning, kill the progress thread on completion
#47, improve the performance of ?==, especially on "//*"
#68, improve the docs for addOracle
#55, ensure if you need phony targets you rebuild every time
#52, ensure all command output is printed
#20, document preferred compilation flags
#20, speed up the Shake executable with GHC RTS flags
#39, print out more of the version string on database change
#41, require unix-2.6 or above
#48, make it clear filetimes are hashes
#43, improve the error messages on lint failures
#45, avoid use of nub
#45, avoid use of intersect which is O(n^2)
#26, add newThrottle to create throttling resources
#26, add unsafeExtraThread to run more than shakeThreads
#32, add a check that withResources does not call need
#614, support unicode filenames
Require unordered-containers-0.2.1 or above
Reduce stack usage when lint checking
#24, create the output directories for the multiple file rule
Improvements to match Ninja behaviour
Include command/cmd in the default module
#16, change the scoping in subninja
#15, fix up the Ninja default targets
Fix up --version output
Improve progress prediction for the first build
Fix removeFiles when there is a directory argument and a pattern
Delete shakeDeterministic, shakeThreads=1 has the same effect
Fix writeFileChanged for line endings on Windows
Support arguments to --progress
Set the number of capabilities based on -j flags
Add shakeTimings, to time the separate stages
Add AssumeSkip, mostly for benchmarking
Normalise file arguments before calling want
Expose ShakeException
Add isFailure to ShakeProgress, and display in progressDisplay
Add withResources
Add -<.> alias for replaceExtension
Add selectors on Stdout/Stdin/Exit
Add CmdResult instance for ExitCode
Upgrade to Flot-0.8
Small documentation markup fixes
Require process-1.1 or above
Improve progress guesses (use exponential decay of work rate)
Improve profiling report error messages
Add a Command module, with alternatives to system' etc.
#593, don't assume doesDirectoryExist = not . doesFileExist
#594, swap how traced messages are printed out
Add Chatty verbosity, for what was Loud
Make repeated --verbose keep increasing the verbosity
If shakeThreads==1 then always use a deterministic pool
Add shakeLineBuffering, defaulting to True
Improve the performance of profiling
Documentation and corrections improvements
Eliminate StepKey from the profiling output
Add a --no-time flag
Makefile improvements
Avoid use of ghc-options in .cabal file
Allow the shake executable to build
Add phony, for writing phony actions
Add removeFilesAfter
Switch to the new profiling code
Add actionOnException and actionFinally
Add shakeArgsWith
Rename shakeWithArgs to shakeArgs and change the clean argument
Remove the -f alias for --flush
Add a shake executable which runs Makefiles
Rename shake to shake-test
Change how progress messages are written
Do not write a beep in progressDisplay, avoids a beep
Add exe function to FilePath
GHC head (7.7) compatibility by removing the Rules fundep
Make the tests work on Linux
Fix report generation on machines whose text format is not ASCII
Make Directory functions work the same on Linux/Mac
Change shakeVersion to be a String
Stop alwaysRerun causing lint failures
Make shakeLint check that the current directory does not change
Add shakeOutput setting
Add removeFiles function
Add Sys module for writing consise system calls
Add getEnv function
Add shakeWithArgs and shakeOptDescrs
Add newCache to cache the parsed contents of files
Add newResourceIO and move newResource into the Rules monad
Add shakeStorageLog, to help diagnosing obscure database errors
Improve the Oracle documentation
Allow getDirectoryFiles to operate recursively
Change getDirectoryFiles to take a set of file patterns
Add doesDirectoryExist function
Add shakeAbbreviations feature
Add a new Progress module for sensible progress messages
Spawn shakeProgress on a separate thread, a safer default
Improve the runtime error messages
Add a quietly function, to hide traced commands
Print main status messages when running a traced command
Display the exit code when a system command fails
Fix AssumeClean when the result exists but has never been built
IMPORTANT: Incompatible on disk format change
Change the storage to not write messages on --silent
Add Applicative on Rules
Add Applicative on Action
Make addOracle return a result of askOracle
Export the class bodies from Classes
Don't export ShakeValue from Classes
IMPORTANT: Incompatible on disk format change
Add the ShakeValue constraint synonym
Change the Oracle to be strongly typed
Add a Classes module
Add shakeFlush to control how often flush is called
Fix a serious space leak in the thread pool
#502, add shakeAssume to assume files are clean/dirty
Remove validStored, replace with storedValue
Remove the default validStored class, almost never right
Remove Eq/Ord from ShakeOptions (now contains a func)
#501, add statistics gathering functions to help report progress
Ensure registering witnesses is thread safe
Ensure GHC does not over-optimise type registration
Add Paths.hs so you can run the tests from the tarball
Don't rely on toList returning a consistent order
Allow hashable-1.2
Fix up FilePattern so "foo//bar" ?== "foo/bar"
Update the cabal file
Add addOracles, for implementing more advanced oracles
Add withoutActions, for implementing command line arguments
#571, vastly improve the correctness of FilePattern
#574, documentation typos
Expose rulePriority
Update documentation with links to ICFP 2012 paper/talk
Minor refactorings
Fix cabal specification on non-Windows
Don't use syntax also stolen by QuasiQuotes
Avoid warnings about unused monadic values
Fix up getModificationTime for GHC 7.6
Don't assume catch is exported by Prelude (GHC 7.6 compat)
Improve the error message when failing to build with *>> or ?>>
Introduce a portable flag, to switch to portable FileTime ops
Improve the error message when failing to build a file
Ensure errors raised bubble up quickly
Significant improvements to the profile output
Only trace the program name by default, not the entire command
Allow unordered-containers < 0.2 again
Intern all keys, so they are only stored once
Optimise modification time checking on Unix
Optimise modification time checking on Windows
Make some fields smaller on disk
IMPORTANT: Incompatible on disk format change
Switch to ByteString for storing File
Add shakeDeterministic, along with a default random pool
Make the Monad/Monoid instance for Rules strict
#550, ensure the journal thread is locked
#550, if your thread dies while reading the database then die
#550, ensure you reset to before the slop before writing
If the witness table is completely corrupt give a better error
Make storage work with exceptions whose messages raise errors
Journal error conditions, to ensure they don't repeat
Better messages on invalid database versions
Complete rewrite of the storage layer and journal design
IMPORTANT: Incompatible on disk format change
IMPORTANT: #546, don't save the database to where it was created
Add systemCwd for running with a particular current directory
Ensure the database is saved to where it was created
#545, make sure if shake is killed, it kills its children
Require unordered-containers 2.1 or higher, fixes bugs
Allow transformers-0.3.*
Add a random script generator and tester
Improve the documentation for withResource
Fix the unordered-containers constraint, was too loose
Don't write report generation messages in Quiet mode
Add ?>> operator, a generalisation of *>>
Rename shakeDump to shakeReport
Add profile report generator
#530, require unordered-containers >=
Improve the documentation code fragments (more links)
Add support for managing finite resources
Require hashable-, which has a TypeRep instance
Add Data/Typeable instances for ShakeOptions
Add Data instance for Verbosity
Include the C example source files
Significant documentation improvements
Create the shakeFiles directory if missing
Allow deepseq-1.3.*
Add a basic lint checking mode
Remove the Dirty state entirely (was incorrect)
Put diagnostics in more places
Add a C example
Add shakeStaunch
Rename shakeParallel to shakeThreads
Delete the lint support (never actually worked)
Completely rewrite the central build algorithm
Add verbosity Diagnostic
Improve FilePath.normalise
Add writeFileChanged
Add systemOutput
Add an Oracle module
Add an explicit Verbosity type
Change to lower precedence for *> etc
Allow deepseq-1.2
Don't export currentRule/currentStack
Fix **>, was matching the wrong way round
Fix FilePath normalise so it works properly on Windows
Properly detect recursive rules, instead of looping
Add *>> for building multiple files at once
Fix a bug where a file rule could return with a lazy error
Make sure all the files are stored in binary, not text
Fix a pattern match error in getDirectoryFiles
Add a warning in the description
Significantly improved documentation
system' now takes an initial argument for the program
Many changes to signatures, some basic documentation
Additional demo, to build shake itself
Initial version, not ready for public use