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