diff options
author | romes <rodrigo.m.mesquita@gmail.com> | 2023-03-13 15:04:28 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2023-05-04 14:58:14 -0400 |
commit | 3fdb18f8df209ebfee51f16288c46acd1ca024b2 (patch) | |
tree | 8b035a10a8c03031ad11fc74080bcfe582ea465c /utils | |
parent | 8cc9a534951d8352c31c9a21f5f91bbf188722b2 (diff) | |
download | haskell-3fdb18f8df209ebfee51f16288c46acd1ca024b2.tar.gz |
Hardwire a better unit-id for ghc
Previously, the unit-id of ghc-the-library was fixed as `ghc`.
This was done primarily because the compiler must know the unit-id of
some packages (including ghc) a-priori to define wired-in names.
However, as seen in #20742, a reinstallable `ghc` whose unit-id is fixed
to `ghc` might result in subtle bugs when different ghc's interact.
A good example of this is having GHC_A load a plugin compiled by GHC_B,
where GHC_A and GHC_B are linked to ghc-libraries that are ABI
incompatible. Without a distinction between the unit-id of the ghc library
GHC_A is linked against and the ghc library the plugin it is loading was
compiled against, we can't check compatibility.
This patch gives a slightly better unit-id to ghc (ghc-version) by
(1) Not setting -this-unit-id to ghc, but rather to the new unit-id (modulo stage0)
(2) Adding a definition to `GHC.Settings.Config` whose value is the new unit-id.
(2.1) `GHC.Settings.Config` is generated by Hadrian
(2.2) and also by cabal through `compiler/Setup.hs`
This unit-id definition is imported by `GHC.Unit.Types` and used to
set the wired-in unit-id of "ghc", which was previously fixed to "ghc"
The commits following this one will improve the unit-id with a
cabal-style package hash and check compatibility when loading plugins.
Note that we also ensure that ghc's unit key matches unit id both when
hadrian or cabal builds ghc, and in this way we no longer need to add
`ghc` to the WiringMap.
Diffstat (limited to 'utils')
-rw-r--r-- | utils/count-deps/Main.hs | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/utils/count-deps/Main.hs b/utils/count-deps/Main.hs index d431f00dda..1b249047d5 100644 --- a/utils/count-deps/Main.hs +++ b/utils/count-deps/Main.hs @@ -56,25 +56,28 @@ calcDeps modName libdir = logger <- getLogger (df, _, _) <- parseDynamicFlags logger df [noLoc "-package=ghc"] setSessionDynFlags df - env <- getSession - loop env Map.empty [mkModuleName modName] + case lookup "Project Unit Id" (compilerInfo df) of + Nothing -> fail "failed to find ghc's unit-id in the compiler info" + Just ghcUnitId -> do + env <- getSession + loop ghcUnitId env Map.empty [mkModuleName modName] where -- Source imports are only guaranteed to show up in the 'mi_deps' -- of modules that import them directly and don’t propagate -- transitively so we loop. - loop :: HscEnv -> Map.Map ModuleName [ModuleName] -> [ModuleName] -> Ghc (Map.Map ModuleName [ModuleName]) - loop env modules (m : ms) = + loop :: String -> HscEnv -> Map.Map ModuleName [ModuleName] -> [ModuleName] -> Ghc (Map.Map ModuleName [ModuleName]) + loop ghcUnitId env modules (m : ms) = if m `Map.member` modules - then loop env modules ms + then loop ghcUnitId env modules ms else do - mi <- liftIO $ hscGetModuleInterface env (mkModule m) + mi <- liftIO $ hscGetModuleInterface env (mkModule ghcUnitId m) let deps = modDeps mi modules <- return $ Map.insert m [] modules - loop env (Map.insert m deps modules) $ ms ++ filter (not . (`Map.member` modules)) deps - loop _ modules [] = return modules + loop ghcUnitId env (Map.insert m deps modules) $ ms ++ filter (not . (`Map.member` modules)) deps + loop _ _ modules [] = return modules - mkModule :: ModuleName -> Module - mkModule = Module (stringToUnit "ghc") + mkModule :: String -> ModuleName -> Module + mkModule ghcUnitId = Module (stringToUnit ghcUnitId) modDeps :: ModIface -> [ModuleName] modDeps mi = map (gwib_mod . snd) $ Set.toList $ dep_direct_mods (mi_deps mi) |