@@ -106,7 +106,7 @@ convGPD os arch comp strfl pi
106
106
(GenericPackageDescription pkg flags libs exes tests benchs) =
107
107
let
108
108
fds = flagInfo strfl flags
109
- conv = convCondTree os arch comp pi fds ( const True )
109
+ conv = convBuildableCondTree os arch comp pi fds
110
110
in
111
111
PInfo
112
112
(maybe [] (conv ComponentLib libBuildInfo ) libs ++
@@ -128,18 +128,68 @@ prefix f fds = [f (concat fds)]
128
128
flagInfo :: Bool -> [PD. Flag ] -> FlagInfo
129
129
flagInfo strfl = M. fromList . L. map (\ (MkFlag fn _ b m) -> (fn, FInfo b m (not (strfl || m))))
130
130
131
+ -- | Extract buildable condition from a cond tree.
132
+ --
133
+ -- Background: If the conditions in a cond tree lead to Buildable being set to False,
134
+ -- then none of the dependencies for this cond tree should actually be taken into
135
+ -- account. On the other hand, some of the flags may only be decided in the solver,
136
+ -- so we cannot necessarily make the decision whether a component is Buildable or not
137
+ -- prior to solving.
138
+ --
139
+ -- What we are doing here is to partially evaluate a condition tree in order to extract
140
+ -- the condition under which Buildable is True.
141
+ extractCondition :: Eq v => (a -> Bool ) -> CondTree v [c ] a -> Condition v
142
+ extractCondition p = go
143
+ where
144
+ go (CondNode x _ cs) | not (p x) = Lit False
145
+ | otherwise = goList cs
146
+
147
+ goList [] = Lit True
148
+ goList ((c, t, e) : cs) =
149
+ let
150
+ ct = go t
151
+ ce = maybe (Lit True ) go e
152
+ in
153
+ ((c `cand` ct) `cor` (CNot c `cand` ce)) `cand` goList cs
154
+
155
+ cand (Lit False ) _ = Lit False
156
+ cand _ (Lit False ) = Lit False
157
+ cand (Lit True ) x = x
158
+ cand x (Lit True ) = x
159
+ cand x y = CAnd x y
160
+
161
+ cor (Lit True ) _ = Lit True
162
+ cor _ (Lit True ) = Lit True
163
+ cor (Lit False ) x = x
164
+ cor x (Lit False ) = x
165
+ cor c (CNot d)
166
+ | c == d = Lit True
167
+ cor x y = COr x y
168
+
169
+ -- | Convert a condition tree to flagged dependencies.
170
+ --
171
+ -- In addition, tries to determine under which condition the condition tree
172
+ -- is buildable, and will add an additional condition on top accordingly.
173
+ convBuildableCondTree :: OS -> Arch -> CompilerInfo -> PI PN -> FlagInfo ->
174
+ Component ->
175
+ (a -> BuildInfo ) ->
176
+ CondTree ConfVar [Dependency ] a -> FlaggedDeps Component PN
177
+ convBuildableCondTree os arch cinfo pi fds comp getInfo t =
178
+ case extractCondition (buildable . getInfo) t of
179
+ Lit True -> convCondTree os arch cinfo pi fds comp getInfo t
180
+ Lit False -> []
181
+ c -> convBranch os arch cinfo pi fds comp getInfo (c, t, Nothing )
182
+
131
183
-- | Convert condition trees to flagged dependencies.
132
184
convCondTree :: OS -> Arch -> CompilerInfo -> PI PN -> FlagInfo ->
133
- (a -> Bool ) -> -- how to detect if a branch is active
134
185
Component ->
135
186
(a -> BuildInfo ) ->
136
187
CondTree ConfVar [Dependency ] a -> FlaggedDeps Component PN
137
- convCondTree os arch cinfo pi @ (PI pn _) fds p comp getInfo (CondNode info ds branches)
138
- | p info = L. map (\ d -> D. Simple (convDep pn d) comp) ds -- unconditional package dependencies
188
+ convCondTree os arch cinfo pi @ (PI pn _) fds comp getInfo (CondNode info ds branches) =
189
+ L. map (\ d -> D. Simple (convDep pn d) comp) ds -- unconditional package dependencies
139
190
++ L. map (\ e -> D. Simple (Ext e) comp) (PD. allExtensions bi) -- unconditional extension dependencies
140
191
++ L. map (\ l -> D. Simple (Lang l) comp) (PD. allLanguages bi) -- unconditional language dependencies
141
- ++ concatMap (convBranch os arch cinfo pi fds p comp getInfo) branches
142
- | otherwise = []
192
+ ++ concatMap (convBranch os arch cinfo pi fds comp getInfo) branches
143
193
where
144
194
bi = getInfo info
145
195
@@ -153,15 +203,14 @@ convCondTree os arch cinfo pi@(PI pn _) fds p comp getInfo (CondNode info ds bra
153
203
-- simple flag choices.
154
204
convBranch :: OS -> Arch -> CompilerInfo ->
155
205
PI PN -> FlagInfo ->
156
- (a -> Bool ) -> -- how to detect if a branch is active
157
206
Component ->
158
207
(a -> BuildInfo ) ->
159
208
(Condition ConfVar ,
160
209
CondTree ConfVar [Dependency ] a ,
161
210
Maybe (CondTree ConfVar [Dependency ] a )) -> FlaggedDeps Component PN
162
- convBranch os arch cinfo pi @ (PI pn _) fds p comp getInfo (c', t', mf') =
163
- go c' ( convCondTree os arch cinfo pi fds p comp getInfo t')
164
- (maybe [] (convCondTree os arch cinfo pi fds p comp getInfo) mf')
211
+ convBranch os arch cinfo pi @ (PI pn _) fds comp getInfo (c', t', mf') =
212
+ go c' ( convCondTree os arch cinfo pi fds comp getInfo t')
213
+ (maybe [] (convCondTree os arch cinfo pi fds comp getInfo) mf')
165
214
where
166
215
go :: Condition ConfVar ->
167
216
FlaggedDeps Component PN -> FlaggedDeps Component PN -> FlaggedDeps Component PN
0 commit comments