Skip to content

Commit 99ea7c2

Browse files
TeofilCmpickering
andcommitted
Support getting nonreinstallable units from GHC
In short, this change allows reinstalling packages like `base` and `template-haskell` with GHC >9.14, and it doesn't modify the behaviour of cabal-install with older versions of GHC for backwards-compatibility. cabal-install includes a hardcoded list of non-reinstallable packages. cabal-install will refuse to use a different version of these packages in a build plan unless the --allow-boot-library-installs flag is set. This list of packages is too pessimistic, and needlessly coupled to GHC. For instance, as of GHC-9.12, `base` and `template-haskell` can be "re-installed" without issue. This patch allows compilers to specify exactly which packages are wired-in and so should not be reinstalled. In the case of GHC-9.14+, this amounts to ghc-internal and ghc itself. If a compiler chooses to specify this information then it overrides the hardcoded non-reinstallable package list. Otherwise, it is still used for the sake of backwards compatibility. Note that this information comes in the form of unit-ids rather than package names. This patch extends the solver with constraints that force the use of a precise unit-id. The behaviour here is still somewhat pessimistic. In the future, we could further relax this restriction and only ban reinstalling these packafes when absolutely necessary, eg, only ban re-installing `ghc` if we are using plugins, etc. For the GHC change that added the interface to expose the unit-id of ghc-internal, see: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/13297 Resolves #10087 Co-Authored-By: Matthew Pickering <matthewtpickering@gmail.com>
1 parent 8bd0d51 commit 99ea7c2

File tree

16 files changed

+83
-6
lines changed

16 files changed

+83
-6
lines changed

Cabal-syntax/src/Distribution/Compiler.hs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,10 @@ import Language.Haskell.Extension
5656
import Distribution.Version (Version, mkVersion', nullVersion)
5757

5858
import qualified Distribution.Compat.CharParsing as P
59+
import Distribution.Package (PackageName)
5960
import Distribution.Parsec (Parsec (..))
6061
import Distribution.Pretty (Pretty (..), prettyShow)
62+
import Distribution.Types.UnitId (UnitId)
6163
import qualified System.Info (compilerName, compilerVersion)
6264
import qualified Text.PrettyPrint as Disp
6365

@@ -213,6 +215,11 @@ data CompilerInfo = CompilerInfo
213215
-- ^ Supported language standards, if known.
214216
, compilerInfoExtensions :: Maybe [Extension]
215217
-- ^ Supported extensions, if known.
218+
, compilerInfoWiredInUnitIds :: Maybe [(PackageName, UnitId)]
219+
-- ^ 'UnitId's that the compiler doesn't support reinstalling.
220+
-- For instance, when using GHC plugins, one wants to use the
221+
-- exact same version of the `ghc` package as the one the
222+
-- compiler was linked against.
216223
}
217224
deriving (Generic, Show, Read)
218225

@@ -244,4 +251,4 @@ abiTagString (AbiTag tag) = tag
244251
-- compiler id's.
245252
unknownCompilerInfo :: CompilerId -> AbiTag -> CompilerInfo
246253
unknownCompilerInfo compilerId abiTag =
247-
CompilerInfo compilerId abiTag (Just []) Nothing Nothing
254+
CompilerInfo compilerId abiTag (Just []) Nothing Nothing Nothing

Cabal-tests/tests/UnitTests/Distribution/Simple/Program/GHC.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ tests = testGroup "Distribution.Simple.Program.GHC"
5454
, compilerLanguages = []
5555
, compilerExtensions = []
5656
, compilerProperties = Map.singleton "Support parallel --make" "YES"
57+
, compilerWiredInUnitIds = Nothing
5758
})
5859
(Platform X86_64 Linux)
5960
(mempty { ghcOptNumJobs = Flag (NumJobs (Just 4)) })

Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ md5CheckGenericPackageDescription proxy = md5Check proxy
3333

3434
md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion
3535
md5CheckLocalBuildInfo proxy = md5Check proxy
36-
0xea86b170fa32ac289cbd1fb6174b5cbf
36+
0xed69bb9372239b67b14b3e4dd3597c56

Cabal/src/Distribution/Simple/Compiler.hs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,9 @@ import Distribution.Pretty
9898
import Prelude ()
9999

100100
import Distribution.Compiler
101+
import Distribution.Package (PackageName)
101102
import Distribution.Simple.Utils
103+
import Distribution.Types.UnitId (UnitId)
102104
import Distribution.Utils.Path
103105
import Distribution.Version
104106

@@ -120,6 +122,11 @@ data Compiler = Compiler
120122
-- ^ Supported language standards.
121123
, compilerExtensions :: [(Extension, Maybe CompilerFlag)]
122124
-- ^ Supported extensions.
125+
, compilerWiredInUnitIds :: Maybe [(PackageName, UnitId)]
126+
-- ^ 'UnitId's that the compiler doesn't support reinstalling.
127+
-- For instance, when using GHC plugins, one wants to use the
128+
-- exact same version of the `ghc` package as the one the
129+
-- compiler was linked against.
123130
, compilerProperties :: Map String String
124131
-- ^ A key-value map for properties not covered by the above fields.
125132
}
@@ -178,6 +185,7 @@ compilerInfo c =
178185
(Just . compilerCompat $ c)
179186
(Just . map fst . compilerLanguages $ c)
180187
(Just . map fst . compilerExtensions $ c)
188+
(compilerWiredInUnitIds c)
181189

182190
-- ------------------------------------------------------------
183191

Cabal/src/Distribution/Simple/GHC.hs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,9 @@ configureCompiler verbosity hcPath conf0 = do
229229
compilerId :: CompilerId
230230
compilerId = CompilerId GHC ghcVersion
231231

232+
projectUnitId :: Maybe String
233+
projectUnitId = Map.lookup "Project Unit Id" ghcInfoMap
234+
232235
-- The @AbiTag@ is the @Project Unit Id@ but with redundant information from the compiler version removed.
233236
-- For development versions of the compiler these look like:
234237
-- @Project Unit Id@: "ghc-9.13-inplace"
@@ -241,9 +244,17 @@ configureCompiler verbosity hcPath conf0 = do
241244
NoAbiTag
242245
AbiTag
243246
( dropWhile (== '-') . stripCommonPrefix (prettyShow compilerId)
244-
<$> Map.lookup "Project Unit Id" ghcInfoMap
247+
<$> projectUnitId
245248
)
246249

250+
wiredInUnitIds = do
251+
ghcInternalUnitId <- Map.lookup "ghc-internal Unit Id" ghcInfoMap
252+
ghcUnitId <- projectUnitId
253+
pure
254+
[ (mkPackageName "ghc", mkUnitId ghcUnitId)
255+
, (mkPackageName "ghc-internal", mkUnitId ghcInternalUnitId)
256+
]
257+
247258
let comp =
248259
Compiler
249260
{ compilerId
@@ -252,6 +263,7 @@ configureCompiler verbosity hcPath conf0 = do
252263
, compilerLanguages = languages
253264
, compilerExtensions = extensions
254265
, compilerProperties = ghcInfoMap
266+
, compilerWiredInUnitIds = wiredInUnitIds
255267
}
256268
compPlatform = Internal.targetPlatform ghcInfo
257269
return (comp, compPlatform, progdb1)

Cabal/src/Distribution/Simple/GHCJS.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ configureCompiler verbosity hcPath conf0 = do
168168
, compilerLanguages = languages
169169
, compilerExtensions = extensions
170170
, compilerProperties = ghcInfoMap
171+
, compilerWiredInUnitIds = Nothing
171172
}
172173
compPlatform = Internal.targetPlatform ghcjsInfo
173174
return (comp, compPlatform, progdb1)

Cabal/src/Distribution/Simple/UHC.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ configure verbosity hcPath progdb = do
7777
, compilerLanguages = uhcLanguages
7878
, compilerExtensions = uhcLanguageExtensions
7979
, compilerProperties = Map.empty
80+
, compilerWiredInUnitIds = Nothing
8081
}
8182
compPlatform = Nothing
8283
return (comp, compPlatform, progdb')

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ showFR _ UnknownPackage = " (unknown package)"
295295
showFR _ (GlobalConstraintVersion vr (ConstraintSourceProjectConfig pc)) = '\n' : (render . nest 6 $ docProjectConfigPathFailReason vr pc)
296296
showFR _ (GlobalConstraintVersion vr src) = " (" ++ constraintSource src ++ " requires " ++ prettyShow vr ++ ")"
297297
showFR _ (GlobalConstraintInstalled src) = " (" ++ constraintSource src ++ " requires installed instance)"
298+
showFR _ (GlobalConstraintInstalledSpecificUnitId unitId src) = " (" ++ constraintSource src ++ " requires installed instance with unit id " ++ prettyShow unitId ++ ")"
298299
showFR _ (GlobalConstraintSource src) = " (" ++ constraintSource src ++ " requires source instance)"
299300
showFR _ (GlobalConstraintFlag src) = " (" ++ constraintSource src ++ " requires opposite flag selection)"
300301
showFR _ ManualFlag = " (manual flag can only be changed explicitly)"

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module Distribution.Solver.Modular.Package
1010
, PN
1111
, QPV
1212
, instI
13+
, instUid
1314
, makeIndependent
1415
, primaryPP
1516
, setupPP
@@ -77,6 +78,10 @@ instI :: I -> Bool
7778
instI (I _ (Inst _)) = True
7879
instI _ = False
7980

81+
instUid :: UnitId -> I -> Bool
82+
instUid uid (I _ (Inst uid')) = uid == uid'
83+
instUid _ _ = False
84+
8085
-- | Is the package in the primary group of packages. This is used to
8186
-- determine (1) if we should try to establish stanza preferences
8287
-- for this goal, and (2) whether or not a user specified @--constraint@

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,9 @@ processPackageConstraintP qpn c i (LabeledPackageConstraint (PackageConstraint s
190190
go _ PackagePropertyInstalled
191191
| instI i = r
192192
| otherwise = Fail c (GlobalConstraintInstalled src)
193+
go _ (PackagePropertyInstalledSpecificUnitId unitId)
194+
| instUid unitId i = r
195+
| otherwise = Fail c (GlobalConstraintInstalledSpecificUnitId unitId src)
193196
go _ PackagePropertySource
194197
| not (instI i) = r
195198
| otherwise = Fail c (GlobalConstraintSource src)

0 commit comments

Comments
 (0)