+-- ABI hash support
+
+{-
+ ghc --abi-hash Data.Foo System.Bar
+
+Generates a combined hash of the ABI for modules Data.Foo and
+System.Bar. The modules must already be compiled, and appropriate -i
+options may be necessary in order to find the .hi files.
+
+This is used by Cabal for generating the InstalledPackageId for a
+package. The InstalledPackageId must change when the visible ABI of
+the package chagnes, so during registration Cabal calls ghc --abi-hash
+to get a hash of the package's ABI.
+-}
+
+abiHash :: [(String, Maybe Phase)] -> Ghc ()
+abiHash strs = do
+ hsc_env <- getSession
+ let dflags = hsc_dflags hsc_env
+
+ liftIO $ do
+
+ let find_it str = do
+ let modname = mkModuleName str
+ r <- findImportedModule hsc_env modname Nothing
+ case r of
+ Found _ m -> return m
+ _error -> ghcError $ CmdLineError $ showSDoc $
+ cannotFindInterface dflags modname r
+
+ mods <- mapM find_it (map fst strs)
+
+ let get_iface modl = loadUserInterface False (text "abiHash") modl
+ ifaces <- initIfaceCheck hsc_env $ mapM get_iface mods
+
+ bh <- openBinMem (3*1024) -- just less than a block
+ mapM_ (put_ bh . mi_mod_hash) ifaces
+ f <- fingerprintBinMem bh
+
+ putStrLn (showSDoc (ppr f))
+
+-- -----------------------------------------------------------------------------