Skip to content

Commit 928850d

Browse files
kosmikussebright
authored andcommitted
Properly extract build conditions from condition trees.
When doing the index conversion prior to dependency solving, we now consider the "Buildable" flag for package components. In particular, if the "Buildable" flag of a component is "True" only under certain conditions, then all build dependencies of that component will be placed under the same conditions.
1 parent eab6c53 commit 928850d

File tree

1 file changed

+59
-10
lines changed

1 file changed

+59
-10
lines changed

cabal-install/Distribution/Client/Dependency/Modular/IndexConversion.hs

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ convGPD os arch comp strfl pi
106106
(GenericPackageDescription pkg flags libs exes tests benchs) =
107107
let
108108
fds = flagInfo strfl flags
109-
conv = convCondTree os arch comp pi fds (const True)
109+
conv = convBuildableCondTree os arch comp pi fds
110110
in
111111
PInfo
112112
(maybe [] (conv ComponentLib libBuildInfo ) libs ++
@@ -128,18 +128,68 @@ prefix f fds = [f (concat fds)]
128128
flagInfo :: Bool -> [PD.Flag] -> FlagInfo
129129
flagInfo strfl = M.fromList . L.map (\ (MkFlag fn _ b m) -> (fn, FInfo b m (not (strfl || m))))
130130

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+
131183
-- | Convert condition trees to flagged dependencies.
132184
convCondTree :: OS -> Arch -> CompilerInfo -> PI PN -> FlagInfo ->
133-
(a -> Bool) -> -- how to detect if a branch is active
134185
Component ->
135186
(a -> BuildInfo) ->
136187
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
139190
++ L.map (\e -> D.Simple (Ext e) comp) (PD.allExtensions bi) -- unconditional extension dependencies
140191
++ 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
143193
where
144194
bi = getInfo info
145195

@@ -153,15 +203,14 @@ convCondTree os arch cinfo pi@(PI pn _) fds p comp getInfo (CondNode info ds bra
153203
-- simple flag choices.
154204
convBranch :: OS -> Arch -> CompilerInfo ->
155205
PI PN -> FlagInfo ->
156-
(a -> Bool) -> -- how to detect if a branch is active
157206
Component ->
158207
(a -> BuildInfo) ->
159208
(Condition ConfVar,
160209
CondTree ConfVar [Dependency] a,
161210
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')
165214
where
166215
go :: Condition ConfVar ->
167216
FlaggedDeps Component PN -> FlaggedDeps Component PN -> FlaggedDeps Component PN

0 commit comments

Comments
 (0)