65bfc8ae0e930dd7228cfe2e427e34c7edabce51
[hadrian.git] / src / Oracles / ArgsHash.hs
1 {-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving #-}
2 module Oracles.ArgsHash (checkArgsHash, argsHashOracle) where
3
4 import Expression
5 import Settings
6 import Settings.Args
7 import Target
8
9 newtype ArgsHashKey = ArgsHashKey Target
10 deriving (Show, Eq, Typeable, Binary, Hashable, NFData)
11
12 -- This is an action that given a full target determines the corresponding
13 -- argument list and computes its hash. The resulting value is tracked in a
14 -- Shake oracle, hence initiating rebuilts when the hash is changed (a hash
15 -- change indicates changes in the build system).
16 -- Note: we keep only the first target input for performance reasons -- to
17 -- avoid storing long lists of source files passed to some builders (e.g. Ar)
18 -- in the Shake database. This optimisation is harmless, because argument list
19 -- constructors are assumed not to examine target sources, but only append them
20 -- to argument lists where appropriate.
21 -- TODO: enforce the above assumption via type trickery?
22 -- TODO: Hash Target to improve accuracy and performance.
23 checkArgsHash :: Target -> Action ()
24 checkArgsHash target = when trackBuildSystem $ do
25 let firstInput = take 1 $ inputs target
26 _ <- askOracle . ArgsHashKey $ target { inputs = firstInput } :: Action Int
27 return ()
28
29 -- Oracle for storing per-target argument list hashes
30 argsHashOracle :: Rules ()
31 argsHashOracle = do
32 _ <- addOracle $ \(ArgsHashKey target) -> hash <$> interpret target getArgs
33 return ()