Skip to content

Commit 04fe295

Browse files
committed
feat: all of it, cabal-install-solver part
1 parent c9852ac commit 04fe295

File tree

23 files changed

+251
-310
lines changed

23 files changed

+251
-310
lines changed

cabal-install-solver/src/Distribution/Solver/Modular.hs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,24 +47,25 @@ import Distribution.Solver.Types.PkgConfigDb
4747
( PkgConfigDb )
4848
import Distribution.Solver.Types.Progress
4949
import Distribution.Solver.Types.Variable
50-
import Distribution.System
51-
( Platform(..) )
50+
5251
import Distribution.Simple.Setup
5352
( BooleanFlag(..) )
5453
import Distribution.Simple.Utils
5554
( ordNubBy )
5655
import Distribution.Verbosity
56+
import Distribution.Solver.Types.Toolchain
5757

5858

5959
-- | Ties the two worlds together: classic cabal-install vs. the modular
6060
-- solver. Performs the necessary translations before and after.
6161
modularResolver :: SolverConfig -> DependencyResolver loc
62-
modularResolver sc (Platform arch os) cinfo iidx sidx pkgConfigDB pprefs pcs pns =
63-
uncurry postprocess <$> -- convert install plan
64-
solve' sc cinfo idx pkgConfigDB pprefs gcs pns
65-
where
62+
modularResolver sc toolchains pkgConfigDbs iidx sidx pprefs pcs pns = do
63+
uncurry postprocess <$> solve' sc cinfo pkgConfigDbs idx pprefs gcs pns
64+
where
65+
cinfo = fst <$> toolchains
66+
6667
-- Indices have to be converted into solver-specific uniform index.
67-
idx = convPIs os arch cinfo gcs (shadowPkgs sc) (strongFlags sc) (solveExecutables sc) iidx sidx
68+
idx = convPIs toolchains gcs (shadowPkgs sc) (strongFlags sc) (solveExecutables sc) iidx sidx
6869
-- Constraints have to be converted into a finite map indexed by PN.
6970
gcs = M.fromListWith (++) (map pair pcs)
7071
where
@@ -114,21 +115,21 @@ modularResolver sc (Platform arch os) cinfo iidx sidx pkgConfigDB pprefs pcs pns
114115
-- complete, i.e., it shows the whole chain of dependencies from the user
115116
-- targets to the conflicting packages.
116117
solve' :: SolverConfig
117-
-> CompilerInfo
118+
-> Staged CompilerInfo
119+
-> Staged (Maybe PkgConfigDb)
118120
-> Index
119-
-> Maybe PkgConfigDb
120121
-> (PN -> PackagePreferences)
121122
-> Map PN [LabeledPackageConstraint]
122123
-> Set PN
123124
-> Progress String String (Assignment, RevDepMap)
124-
solve' sc cinfo idx pkgConfigDB pprefs gcs pns =
125+
solve' sc cinfo pkgConfigDb idx pprefs gcs pns =
125126
toProgress $ retry (runSolver printFullLog sc) createErrorMsg
126127
where
127128
runSolver :: Bool -> SolverConfig
128129
-> RetryLog String SolverFailure (Assignment, RevDepMap)
129130
runSolver keepLog sc' =
130131
displayLogMessages keepLog $
131-
solve sc' cinfo idx pkgConfigDB pprefs gcs pns
132+
solve sc' cinfo pkgConfigDb idx pprefs gcs pns
132133

133134
createErrorMsg :: SolverFailure
134135
-> RetryLog String String (Assignment, RevDepMap)

cabal-install-solver/src/Distribution/Solver/Modular/ConfiguredConversion.hs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ import Data.Maybe
66
import Prelude hiding (pi)
77
import Data.Either (partitionEithers)
88

9-
import Distribution.Package (UnitId, packageId)
10-
119
import qualified Distribution.Simple.PackageIndex as SI
1210

1311
import Distribution.Solver.Modular.Configured
@@ -21,41 +19,48 @@ import Distribution.Solver.Types.SolverId
2119
import Distribution.Solver.Types.SolverPackage
2220
import Distribution.Solver.Types.InstSolverPackage
2321
import Distribution.Solver.Types.SourcePackage
22+
import Distribution.Solver.Types.Stage (Staged (..))
2423

2524
-- | Converts from the solver specific result @CP QPN@ into
2625
-- a 'ResolverPackage', which can then be converted into
2726
-- the install plan.
28-
convCP :: SI.InstalledPackageIndex ->
27+
convCP :: Staged SI.InstalledPackageIndex ->
2928
CI.PackageIndex (SourcePackage loc) ->
3029
CP QPN -> ResolverPackage loc
3130
convCP iidx sidx (CP qpi fa es ds) =
32-
case convPI qpi of
33-
Left pi -> PreExisting $
31+
case qpi of
32+
-- Installed
33+
(PI qpn (I s _ (Inst pi))) ->
34+
PreExisting $
3435
InstSolverPackage {
35-
instSolverPkgIPI = fromJust $ SI.lookupUnitId iidx pi,
36+
instSolverPkgIPI = ipkg,
37+
instSolverStage = s,
38+
instSolverQPN = qpn,
3639
instSolverPkgLibDeps = fmap fst ds',
3740
instSolverPkgExeDeps = fmap snd ds'
3841
}
39-
Right pi -> Configured $
42+
where
43+
ipkg = fromMaybe (error "convCP: lookupUnitId failed") $
44+
SI.lookupUnitId (getStage iidx s) pi
45+
-- "In repo" i.e. a source package
46+
(PI qpn@(Q _path pn) (I s v InRepo)) ->
47+
let pi = PackageIdentifier pn v in
48+
Configured $
4049
SolverPackage {
41-
solverPkgSource = srcpkg,
50+
solverPkgStage = s,
51+
solverPkgQPN = qpn,
52+
solverPkgSource = fromMaybe (error "convCP: lookupPackageId failed") $ CI.lookupPackageId sidx pi,
4253
solverPkgFlags = fa,
4354
solverPkgStanzas = es,
4455
solverPkgLibDeps = fmap fst ds',
4556
solverPkgExeDeps = fmap snd ds'
4657
}
47-
where
48-
srcpkg = fromMaybe (error "convCP: lookupPackageId failed") $ CI.lookupPackageId sidx pi
4958
where
5059
ds' :: ComponentDeps ([SolverId] {- lib -}, [SolverId] {- exe -})
5160
ds' = fmap (partitionEithers . map convConfId) ds
5261

53-
convPI :: PI QPN -> Either UnitId PackageId
54-
convPI (PI _ (I _ (Inst pi))) = Left pi
55-
convPI pi = Right (packageId (either id id (convConfId pi)))
56-
5762
convConfId :: PI QPN -> Either SolverId {- is lib -} SolverId {- is exe -}
58-
convConfId (PI (Q (PackagePath q) pn) (I v loc)) =
63+
convConfId (PI (Q (PackagePath q) pn) (I _ v loc)) =
5964
case loc of
6065
Inst pi -> Left (PreExistingId sourceId pi)
6166
_otherwise

cabal-install-solver/src/Distribution/Solver/Modular/Explore.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ exploreLog mbj enableBj fineGrainedConflicts (CountConflicts countConflicts) idx
268268
-- Skipping it is an optimization. If false, it returns a new conflict set
269269
-- to be merged with the previous one.
270270
couldResolveConflicts :: QPN -> POption -> S.Set CS.Conflict -> Maybe ConflictSet
271-
couldResolveConflicts currentQPN@(Q _ pn) (POption i@(I v _) _) conflicts =
271+
couldResolveConflicts currentQPN@(Q _ pn) (POption i@(I _ v _) _) conflicts =
272272
let (PInfo deps _ _ _) = idx M.! pn M.! i
273273
qdeps = qualifyDeps currentQPN deps
274274

cabal-install-solver/src/Distribution/Solver/Modular/IndexConversion.hs

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import Distribution.Solver.Types.PackageConstraint
3434
import qualified Distribution.Solver.Types.PackageIndex as CI
3535
import Distribution.Solver.Types.Settings
3636
import Distribution.Solver.Types.SourcePackage
37+
import Distribution.Solver.Types.Stage (Stage(..), Staged(..))
38+
import qualified Distribution.Solver.Types.Stage as Stage
3739

3840
import Distribution.Solver.Modular.Dependency as D
3941
import Distribution.Solver.Modular.Flag as F
@@ -53,21 +55,27 @@ import Distribution.Solver.Modular.Version
5355
-- resolving these situations. However, the right thing to do is to
5456
-- fix the problem there, so for now, shadowing is only activated if
5557
-- explicitly requested.
56-
convPIs :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint]
57-
-> ShadowPkgs -> StrongFlags -> SolveExecutables
58-
-> SI.InstalledPackageIndex -> CI.PackageIndex (SourcePackage loc)
59-
-> Index
60-
convPIs os arch comp constraints sip strfl solveExes iidx sidx =
58+
convPIs
59+
:: Staged (CompilerInfo, Platform)
60+
-> Map PN [LabeledPackageConstraint]
61+
-> ShadowPkgs
62+
-> StrongFlags
63+
-> SolveExecutables
64+
-> Staged SI.InstalledPackageIndex
65+
-> CI.PackageIndex (SourcePackage loc)
66+
-> Index
67+
convPIs toolchains' constraints sip strfl solveExes iidx sidx =
6168
mkIndex $
62-
convIPI' sip iidx ++ convSPI' os arch comp constraints strfl solveExes sidx
69+
convIPI' sip iidx ++ convSPI' toolchains' constraints strfl solveExes sidx
6370

6471
-- | Convert a Cabal installed package index to the simpler,
6572
-- more uniform index format of the solver.
66-
convIPI' :: ShadowPkgs -> SI.InstalledPackageIndex -> [(PN, I, PInfo)]
67-
convIPI' (ShadowPkgs sip) idx =
73+
convIPI' :: ShadowPkgs -> Staged SI.InstalledPackageIndex -> [(PN, I, PInfo)]
74+
convIPI' (ShadowPkgs sip) =
75+
Stage.foldMapWithKey $ \stage idx ->
6876
-- apply shadowing whenever there are multiple installed packages with
6977
-- the same version
70-
[ maybeShadow (convIP idx pkg)
78+
[ maybeShadow (convIP stage idx pkg)
7179
-- IMPORTANT to get internal libraries. See
7280
-- Note [Index conversion with internal libraries]
7381
| (_, pkgs) <- SI.allPackagesBySourcePackageIdAndLibName idx
@@ -80,16 +88,16 @@ convIPI' (ShadowPkgs sip) idx =
8088
shadow x = x
8189

8290
-- | Extract/recover the package ID from an installed package info, and convert it to a solver's I.
83-
convId :: IPI.InstalledPackageInfo -> (PN, I)
84-
convId ipi = (pn, I ver $ Inst $ IPI.installedUnitId ipi)
91+
convId :: Stage -> IPI.InstalledPackageInfo -> (PN, I)
92+
convId stage ipi = (pn, I stage ver $ Inst $ IPI.installedUnitId ipi)
8593
where MungedPackageId mpn ver = mungedId ipi
8694
-- HACK. See Note [Index conversion with internal libraries]
8795
pn = encodeCompatPackageName mpn
8896

8997
-- | Convert a single installed package into the solver-specific format.
90-
convIP :: SI.InstalledPackageIndex -> IPI.InstalledPackageInfo -> (PN, I, PInfo)
91-
convIP idx ipi =
92-
case traverse (convIPId (DependencyReason pn M.empty S.empty) comp idx) (IPI.depends ipi) of
98+
convIP :: Stage -> SI.InstalledPackageIndex -> IPI.InstalledPackageInfo -> (PN, I, PInfo)
99+
convIP stage idx ipi =
100+
case traverse (convIPId stage (DependencyReason pn M.empty S.empty) comp idx) (IPI.depends ipi) of
93101
Left u -> (pn, i, PInfo [] M.empty M.empty (Just (Broken u)))
94102
Right fds -> (pn, i, PInfo fds components M.empty Nothing)
95103
where
@@ -101,7 +109,7 @@ convIP idx ipi =
101109
, compIsBuildable = IsBuildable True
102110
}
103111

104-
(pn, i) = convId ipi
112+
(pn, i) = convId stage ipi
105113

106114
-- 'sourceLibName' is unreliable, but for now we only really use this for
107115
-- primary libs anyways
@@ -141,29 +149,48 @@ convIP idx ipi =
141149
-- May return Nothing if the package can't be found in the index. That
142150
-- indicates that the original package having this dependency is broken
143151
-- and should be ignored.
144-
convIPId :: DependencyReason PN -> Component -> SI.InstalledPackageIndex -> UnitId -> Either UnitId (FlaggedDep PN)
145-
convIPId dr comp idx ipid =
152+
convIPId :: Stage -> DependencyReason PN -> Component -> SI.InstalledPackageIndex -> UnitId -> Either UnitId (FlaggedDep PN)
153+
convIPId stage dr comp idx ipid =
146154
case SI.lookupUnitId idx ipid of
147155
Nothing -> Left ipid
148-
Just ipi -> let (pn, i) = convId ipi
149-
name = ExposedLib LMainLibName -- TODO: Handle sub-libraries.
156+
Just ipi -> let (pn, i) = convId stage ipi
157+
name = ExposedLib LMainLibName -- TODO: Handle sub-libraries.
150158
in Right (D.Simple (LDep dr (Dep (PkgComponent pn name) (Fixed i))) comp)
151159
-- NB: something we pick up from the
152160
-- InstalledPackageIndex is NEVER an executable
153161

154162
-- | Convert a cabal-install source package index to the simpler,
155163
-- more uniform index format of the solver.
156-
convSPI' :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint]
157-
-> StrongFlags -> SolveExecutables
158-
-> CI.PackageIndex (SourcePackage loc) -> [(PN, I, PInfo)]
159-
convSPI' os arch cinfo constraints strfl solveExes =
160-
L.map (convSP os arch cinfo constraints strfl solveExes) . CI.allPackages
164+
-- NOTE: The package description of source package can depent on the platform
165+
-- and compiler version. Here we decide to convert a single source package
166+
-- into multiple index entries, one for each stage, where the conditionals are
167+
-- resolved. This choice might incour in high memory consumption and it might
168+
-- be worth looking for a different approach.
169+
convSPI'
170+
:: Staged (CompilerInfo, Platform)
171+
-> Map PN [LabeledPackageConstraint]
172+
-> StrongFlags
173+
-> SolveExecutables
174+
-> CI.PackageIndex (SourcePackage loc)
175+
-> [(PN, I, PInfo)]
176+
convSPI' toolchains constraints strfl solveExes sidx =
177+
Stage.foldMapWithKey (\stage (cinfo, Platform arch os) ->
178+
L.map (convSP stage os arch cinfo constraints strfl solveExes) (CI.allPackages sidx)
179+
) toolchains
161180

162181
-- | Convert a single source package into the solver-specific format.
163-
convSP :: OS -> Arch -> CompilerInfo -> Map PN [LabeledPackageConstraint]
164-
-> StrongFlags -> SolveExecutables -> SourcePackage loc -> (PN, I, PInfo)
165-
convSP os arch cinfo constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv) gpd _ _pl) =
166-
let i = I pv InRepo
182+
convSP
183+
:: Stage
184+
-> OS
185+
-> Arch
186+
-> CompilerInfo
187+
-> Map PN [LabeledPackageConstraint]
188+
-> StrongFlags
189+
-> SolveExecutables
190+
-> SourcePackage loc
191+
-> (PN, I, PInfo)
192+
convSP stage os arch cinfo constraints strfl solveExes (SourcePackage (PackageIdentifier pn pv) gpd _ _pl) =
193+
let i = I stage pv InRepo
167194
pkgConstraints = fromMaybe [] $ M.lookup pn constraints
168195
in (pn, i, convGPD os arch cinfo pkgConstraints strfl solveExes pn gpd)
169196

cabal-install-solver/src/Distribution/Solver/Modular/Package.hs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import Distribution.Pretty (prettyShow)
2323

2424
import Distribution.Solver.Modular.Version
2525
import Distribution.Solver.Types.PackagePath
26+
import Distribution.Solver.Types.Stage (Stage, showStage)
2627

2728
-- | A package name.
2829
type PN = PackageName
@@ -49,13 +50,13 @@ data Loc = Inst PId | InRepo
4950
deriving (Eq, Ord, Show)
5051

5152
-- | Instance. A version number and a location.
52-
data I = I Ver Loc
53+
data I = I Stage Ver Loc
5354
deriving (Eq, Ord, Show)
5455

5556
-- | String representation of an instance.
5657
showI :: I -> String
57-
showI (I v InRepo) = showVer v
58-
showI (I v (Inst uid)) = showVer v ++ "/installed" ++ extractPackageAbiHash uid
58+
showI (I s v InRepo) = showVer v ++ " (" ++ showStage s ++ ")"
59+
showI (I s v (Inst uid)) = showVer v ++ "/installed" ++ extractPackageAbiHash uid ++ " (" ++ showStage s ++ ")"
5960
where
6061
extractPackageAbiHash xs =
6162
case first reverse $ break (=='-') $ reverse (prettyShow xs) of
@@ -71,5 +72,5 @@ showPI :: PI QPN -> String
7172
showPI (PI qpn i) = showQPN qpn ++ "-" ++ showI i
7273

7374
instI :: I -> Bool
74-
instI (I _ (Inst _)) = True
75+
instI (I _ _ (Inst _)) = True
7576
instI _ = False

cabal-install-solver/src/Distribution/Solver/Modular/Preference.hs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ addWeight :: (PN -> [Ver] -> POption -> Weight) -> EndoTreeTrav d c
7272
addWeight f = addWeights [f]
7373

7474
version :: POption -> Ver
75-
version (POption (I v _) _) = v
75+
version (POption (I _ v _) _) = v
7676

7777
-- | Prefer to link packages whenever possible.
7878
preferLinked :: EndoTreeTrav d c
@@ -139,7 +139,7 @@ preferPackagePreferences pcs =
139139

140140
-- Prefer installed packages over non-installed packages.
141141
installed :: POption -> Weight
142-
installed (POption (I _ (Inst _)) _) = 0
142+
installed (POption (I _ _ (Inst _)) _) = 0
143143
installed _ = 1
144144

145145
-- | Traversal that tries to establish package stanza enable\/disable
@@ -184,7 +184,7 @@ processPackageConstraintP qpn c i (LabeledPackageConstraint (PackageConstraint s
184184
else r
185185
where
186186
go :: I -> PackageProperty -> Tree d c
187-
go (I v _) (PackagePropertyVersion vr)
187+
go (I _ v _) (PackagePropertyVersion vr)
188188
| checkVR vr v = r
189189
| otherwise = Fail c (GlobalConstraintVersion vr src)
190190
go _ PackagePropertyInstalled
@@ -338,10 +338,10 @@ avoidReinstalls p = go
338338
| otherwise = PChoiceF qpn rdm gr cs
339339
where
340340
disableReinstalls =
341-
let installed = [ v | (_, POption (I v (Inst _)) _, _) <- W.toList cs ]
341+
let installed = [ v | (_, POption (I _ v (Inst _)) _, _) <- W.toList cs ]
342342
in W.mapWithKey (notReinstall installed) cs
343343

344-
notReinstall vs (POption (I v InRepo) _) _ | v `elem` vs =
344+
notReinstall vs (POption (I _ v InRepo) _) _ | v `elem` vs =
345345
Fail (varToConflictSet (P qpn)) CannotReinstall
346346
notReinstall _ _ x =
347347
x

cabal-install-solver/src/Distribution/Solver/Modular/Solver.hs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ import Distribution.Solver.Modular.Tree
4444
import qualified Distribution.Solver.Modular.PSQ as PSQ
4545

4646
import Distribution.Simple.Setup (BooleanFlag(..))
47+
import Distribution.Solver.Types.Stage (Staged)
4748

4849
#ifdef DEBUG_TRACETREE
4950
import qualified Distribution.Solver.Modular.ConflictSet as CS
5051
import qualified Distribution.Solver.Modular.WeightedPSQ as W
51-
import qualified Distribution.Deprecated.Text as T
52+
import Distribution.Solver.Modular.Version (showVer)
5253

5354
import Debug.Trace.Tree (gtraceJson)
5455
import Debug.Trace.Tree.Simple
@@ -88,14 +89,14 @@ newtype PruneAfterFirstSuccess = PruneAfterFirstSuccess Bool
8889
-- before exploration.
8990
--
9091
solve :: SolverConfig -- ^ solver parameters
91-
-> CompilerInfo
92+
-> Staged CompilerInfo
93+
-> Staged (Maybe PkgConfigDb)
9294
-> Index -- ^ all available packages as an index
93-
-> Maybe PkgConfigDb -- ^ available pkg-config pkgs
9495
-> (PN -> PackagePreferences) -- ^ preferences
9596
-> M.Map PN [LabeledPackageConstraint] -- ^ global constraints
9697
-> S.Set PN -- ^ global goals
9798
-> RetryLog Message SolverFailure (Assignment, RevDepMap)
98-
solve sc cinfo idx pkgConfigDB userPrefs userConstraints userGoals =
99+
solve sc cinfo pkgConfigDB idx userPrefs userConstraints userGoals =
99100
explorePhase .
100101
traceTree "cycles.json" id .
101102
detectCycles .
@@ -136,7 +137,7 @@ solve sc cinfo idx pkgConfigDB userPrefs userConstraints userGoals =
136137
P.enforceManualFlags userConstraints
137138
validationCata = P.enforceSingleInstanceRestriction .
138139
validateLinking idx .
139-
validateTree cinfo idx pkgConfigDB
140+
validateTree cinfo pkgConfigDB idx
140141
prunePhase = (if asBool (avoidReinstalls sc) then P.avoidReinstalls (const True) else id) .
141142
(case onlyConstrained sc of
142143
OnlyConstrainedAll ->
@@ -203,7 +204,7 @@ instance GSimpleTree (Tree d c) where
203204

204205
-- Show package choice
205206
goP :: QPN -> POption -> Tree d c -> (String, SimpleTree)
206-
goP _ (POption (I ver _loc) Nothing) subtree = (T.display ver, go subtree)
207+
goP _ (POption (I _stage ver _loc) Nothing) subtree = (showVer ver, go subtree)
207208
goP (Q _ pn) (POption _ (Just pp)) subtree = (showQPN (Q pp pn), go subtree)
208209

209210
-- Show flag or stanza choice

0 commit comments

Comments
 (0)