Minor revision.
[hadrian.git] / src / Target.hs
1 {-# LANGUAGE DeriveGeneric, FlexibleInstances #-}
2 module Target (
3 Target (..)
4 , PartialTarget (..)
5 , unsafeFromPartial
6 , fullTarget
7 , fullTargetWithWay
8 ) where
9
10 import Control.Monad.Trans.Reader
11 import GHC.Generics (Generic)
12
13 import Base
14 import Builder
15 import Package
16 import Stage
17 import Way
18
19 -- | Parameters relevant to the current build target.
20 data Target = Target
21 { stage :: Stage -- ^ Stage being built
22 , package :: Package -- ^ Package being built
23 , builder :: Builder -- ^ Builder to be invoked
24 , way :: Way -- ^ Way to build (set to vanilla for most targets)
25 , inputs :: [FilePath] -- ^ Source files passed to the builder
26 , outputs :: [FilePath] -- ^ Files to be produced
27 } deriving (Show, Eq, Generic)
28
29 -- | If values of type @a@ form a 'Monoid' then we can also derive a 'Monoid'
30 -- instance for values of type @'ReaderT' 'Target' 'Action' a@:
31 --
32 -- * the empty computation is the identity element of the underlying type
33 -- * two computations can be combined by combining their results
34 instance Monoid a => Monoid (ReaderT Target Action a) where
35 mempty = return mempty
36 mappend = liftM2 mappend
37
38 -- | A partially constructed Target with fields 'Stage' and 'Package' only.
39 -- 'PartialTarget's are used for generating build rules.
40 data PartialTarget = PartialTarget Stage Package deriving (Eq, Show)
41
42 -- | Convert 'PartialTarget' to a 'Target' assuming that unknown fields won't
43 -- be used.
44 unsafeFromPartial :: PartialTarget -> Target
45 unsafeFromPartial (PartialTarget s p) = Target
46 {
47 stage = s,
48 package = p,
49 builder = error "unsafeFromPartial: builder not set",
50 way = error "unsafeFromPartial: way not set",
51 inputs = error "unsafeFromPartial: inputs not set",
52 outputs = error "unsafeFromPartial: outputs not set"
53 }
54
55 -- | Construct a full 'Target' by augmenting a 'PartialTarget' with missing
56 -- fields. Most targets are built only one way, 'vanilla', hence it is set by
57 -- default. Use 'fullTargetWithWay' otherwise.
58 fullTarget ::
59 PartialTarget
60 -> Builder
61 -> [FilePath] -- ^ Source files
62 -> [FilePath] -- ^ Produced files
63 -> Target
64 fullTarget (PartialTarget s p) b srcs fs = Target
65 {
66 stage = s,
67 package = p,
68 builder = b,
69 way = vanilla,
70 inputs = map unifyPath srcs,
71 outputs = map unifyPath fs
72 }
73
74 -- | Like 'fullTarget', but allows an explicit 'Way' parameter.
75 fullTargetWithWay ::
76 PartialTarget
77 -> Builder
78 -> Way
79 -> [FilePath] -- ^ Source files
80 -> [FilePath] -- ^ Produced files
81 -> Target
82 fullTargetWithWay pt b w srcs fs = (fullTarget pt b srcs fs) { way = w }
83
84 instance Binary Target
85 instance NFData Target
86 instance Hashable Target