Implement install_docs (#442)
[hadrian.git] / src / Expression.hs
1 module Expression (
2 -- * Expressions
3 Expr, Predicate, Args, Ways,
4
5 -- ** Construction and modification
6 expr, exprIO, arg, remove,
7
8 -- ** Predicates
9 (?), stage, stage0, stage1, stage2, notStage0, package, notPackage,
10 libraryPackage, builder, way, input, inputs, output, outputs,
11
12 -- ** Evaluation
13 interpret, interpretInContext,
14
15 -- * Convenient accessors
16 getBuildRoot, getContext, getPkgData, getPkgDataList, getOutputs, getInputs,
17 getInput, getOutput,
18
19 -- * Re-exports
20 module Base,
21 module Builder,
22 module Context,
23 module GHC
24 ) where
25
26 import qualified Hadrian.Expression as H
27 import Hadrian.Expression hiding (Expr, Predicate, Args)
28
29 import Base
30 import Builder
31 import GHC
32 import Context hiding (stage, package, way)
33 import Oracles.PackageData
34
35 -- | @Expr a@ is a computation that produces a value of type @Action a@ and can
36 -- read parameters of the current build 'Target'.
37 type Expr a = H.Expr Context Builder a
38
39 -- | The following expressions are used throughout the build system for
40 -- specifying conditions ('Predicate'), lists of arguments ('Args'), 'Ways'
41 -- and 'Packages'.
42 type Predicate = H.Predicate Context Builder
43 type Args = H.Args Context Builder
44 type Ways = Expr [Way]
45
46 -- | Get a value from the @package-data.mk@ file of the current context.
47 getPkgData :: (FilePath -> PackageData) -> Expr String
48 getPkgData key = expr . pkgData . key =<< getBuildPath
49
50 -- | Get a list of values from the @package-data.mk@ file of the current context.
51 getPkgDataList :: (FilePath -> PackageDataList) -> Expr [String]
52 getPkgDataList key = expr . pkgDataList . key =<< getBuildPath
53
54 -- | Is the build currently in the provided stage?
55 stage :: Stage -> Predicate
56 stage s = (s ==) <$> getStage
57
58 -- | Is a particular package being built?
59 package :: Package -> Predicate
60 package p = (p ==) <$> getPackage
61
62 -- | This type class allows the user to construct both precise builder
63 -- predicates, such as @builder (Ghc CompileHs Stage1)@, as well as predicates
64 -- covering a set of similar builders. For example, @builder (Ghc CompileHs)@
65 -- matches any stage, and @builder Ghc@ matches any stage and any GHC mode.
66 class BuilderPredicate a where
67 -- | Is a particular builder being used?
68 builder :: a -> Predicate
69
70 instance BuilderPredicate Builder where
71 builder b = (b ==) <$> getBuilder
72
73 instance BuilderPredicate a => BuilderPredicate (Stage -> a) where
74 builder f = builder . f =<< getStage
75
76 instance BuilderPredicate a => BuilderPredicate (CcMode -> a) where
77 builder f = do
78 b <- getBuilder
79 case b of
80 Cc c _ -> builder (f c)
81 _ -> return False
82
83 instance BuilderPredicate a => BuilderPredicate (GhcMode -> a) where
84 builder f = do
85 b <- getBuilder
86 case b of
87 Ghc c _ -> builder (f c)
88 _ -> return False
89
90 instance BuilderPredicate a => BuilderPredicate (FilePath -> a) where
91 builder f = do
92 b <- getBuilder
93 case b of
94 Configure path -> builder (f path)
95 _ -> return False
96
97 -- | Is the current build 'Way' equal to a certain value?
98 way :: Way -> Predicate
99 way w = (w ==) <$> getWay
100
101 -- | Is the build currently in stage 0?
102 stage0 :: Predicate
103 stage0 = stage Stage0
104
105 -- | Is the build currently in stage 1?
106 stage1 :: Predicate
107 stage1 = stage Stage1
108
109 -- | Is the build currently in stage 2?
110 stage2 :: Predicate
111 stage2 = stage Stage2
112
113 -- | Is the build /not/ in stage 0 right now?
114 notStage0 :: Predicate
115 notStage0 = notM stage0
116
117 -- | Is a certain package /not/ built right now?
118 notPackage :: Package -> Predicate
119 notPackage = notM . package
120
121 -- | Is a library package currently being built?
122 libraryPackage :: Predicate
123 libraryPackage = isLibrary <$> getPackage