Commit b45332b2 authored by Edward Z. Yang's avatar Edward Z. Yang Committed by Edward Z. Yang
Browse files

New 'abi-depends' field which tracks 'depends' plus 'abi'.



GHC will make use of this to do more accurate shadowing computation,
because now we can tell if something is ABI-compatible, even if the 'id'
matches.
Signed-off-by: default avatarEdward Z. Yang <ezyang@cs.stanford.edu>
parent 3a770783
......@@ -35,6 +35,7 @@ module Distribution.InstalledPackageInfo (
requiredSignatures,
installedOpenUnitId,
ExposedModule(..),
AbiDependency(..),
ParseResult(..), PError(..), PWarning,
emptyInstalledPackageInfo,
parseInstalledPackageInfo,
......@@ -111,6 +112,7 @@ data InstalledPackageInfo
-- INVARIANT: if the package is definite, UnitId is NOT
-- a ComponentId of an indefinite package
depends :: [UnitId],
abiDepends :: [AbiDependency],
ccOptions :: [String],
ldOptions :: [String],
frameworkDirs :: [FilePath],
......@@ -199,6 +201,7 @@ emptyInstalledPackageInfo
includeDirs = [],
includes = [],
depends = [],
abiDepends = [],
ccOptions = [],
ldOptions = [],
frameworkDirs = [],
......@@ -251,6 +254,36 @@ showExposedModules xs
parseExposedModules :: Parse.ReadP r [ExposedModule]
parseExposedModules = parseOptCommaList parse
-- -----------------------------------------------------------------------------
-- ABI dependency
-- | An ABI dependency is a dependency on a library which also
-- records the ABI hash ('abiHash') of the library it depends
-- on.
--
-- The primary utility of this is to enable an extra sanity when
-- GHC loads libraries: it can check if the dependency has a matching
-- ABI and if not, refuse to load this library. This information
-- is critical if we are shadowing libraries; differences in the
-- ABI hash let us know what packages get shadowed by the new version
-- of a package.
data AbiDependency = AbiDependency {
depUnitId :: UnitId,
depAbiHash :: AbiHash
}
deriving (Eq, Generic, Read, Show)
instance Text AbiDependency where
disp (AbiDependency uid abi) =
disp uid <<>> Disp.char '=' <<>> disp abi
parse = do
uid <- parse
_ <- Parse.char '='
abi <- parse
return (AbiDependency uid abi)
instance Binary AbiDependency
-- -----------------------------------------------------------------------------
-- Parsing
......@@ -380,6 +413,9 @@ installedFieldDescrs = [
, listField "depends"
disp parse
depends (\xs pkg -> pkg{depends=xs})
, listField "abi-depends"
disp parse
abiDepends (\xs pkg -> pkg{abiDepends=xs})
, listField "cc-options"
showToken parseTokenQ
ccOptions (\path pkg -> pkg{ccOptions=path})
......
......@@ -212,7 +212,9 @@ buildComponent verbosity numJobs pkg_descr lbi suffixes
pwd <- getCurrentDirectory
let -- The in place registration uses the "-inplace" suffix, not an ABI hash
installedPkgInfo = inplaceInstalledPackageInfo pwd distPref pkg_descr
(mkAbiHash "") lib' lbi clbi
-- NB: Use a fake ABI hash to avoid
-- needing to recompute it every build.
(mkAbiHash "inplace") lib' lbi clbi
debug verbosity $ "Registering inplace:\n" ++ (IPI.showInstalledPackageInfo installedPkgInfo)
registerPackage verbosity (compiler lbi) (withPrograms lbi) HcPkg.MultiInstance
......
......@@ -99,6 +99,7 @@ toCurrent ipi@InstalledPackageInfo{} =
Current.includeDirs = includeDirs ipi,
Current.includes = includes ipi,
Current.depends = map (Current.mkLegacyUnitId . convertPackageId) (depends ipi),
Current.abiDepends = [],
Current.ccOptions = ccOptions ipi,
Current.ldOptions = ldOptions ipi,
Current.frameworkDirs = frameworkDirs ipi,
......
......@@ -37,6 +37,7 @@ module Distribution.Simple.Register (
createPackageDB,
deletePackageDB,
abiHash,
invokeHcPkg,
registerPackage,
generateRegistrationInfo,
......@@ -220,20 +221,7 @@ generateRegistrationInfo verbosity pkg lib lbi clbi inplace reloc distPref packa
--TODO: eliminate pwd!
pwd <- getCurrentDirectory
--TODO: the method of setting the UnitId is compiler specific
-- this aspect should be delegated to a per-compiler helper.
let comp = compiler lbi
lbi' = lbi {
withPackageDB = withPackageDB lbi
++ [SpecificPackageDB (internalPackageDBPath lbi distPref)]
}
abi_hash <-
case compilerFlavor comp of
GHC | compilerVersion comp >= mkVersion [6,11] -> do
fmap mkAbiHash $ GHC.libAbiHash verbosity pkg lbi' lib clbi
GHCJS -> do
fmap mkAbiHash $ GHCJS.libAbiHash verbosity pkg lbi' lib clbi
_ -> return (mkAbiHash "")
abi_hash <- abiHash verbosity pkg distPref lbi lib clbi
installedPkgInfo <-
if inplace
......@@ -248,6 +236,28 @@ generateRegistrationInfo verbosity pkg lib lbi clbi inplace reloc distPref packa
return installedPkgInfo{ IPI.abiHash = abi_hash }
-- | Compute the 'AbiHash' of a library that we built inplace.
abiHash :: Verbosity
-> PackageDescription
-> FilePath
-> LocalBuildInfo
-> Library
-> ComponentLocalBuildInfo
-> IO AbiHash
abiHash verbosity pkg distPref lbi lib clbi =
case compilerFlavor comp of
GHC | compilerVersion comp >= mkVersion [6,11] -> do
fmap mkAbiHash $ GHC.libAbiHash verbosity pkg lbi' lib clbi
GHCJS -> do
fmap mkAbiHash $ GHCJS.libAbiHash verbosity pkg lbi' lib clbi
_ -> return (mkAbiHash "")
where
comp = compiler lbi
lbi' = lbi {
withPackageDB = withPackageDB lbi
++ [SpecificPackageDB (internalPackageDBPath lbi distPref)]
}
relocRegistrationInfo :: Verbosity
-> PackageDescription
-> Library
......@@ -412,9 +422,8 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi
IPI.extraGHCiLibraries = extraGHCiLibs bi,
IPI.includeDirs = absinc ++ adjustRelIncDirs relinc,
IPI.includes = includes bi,
--TODO: unclear what the root cause of the
-- duplication is, but we nub it here for now:
IPI.depends = ordNub $ map fst (componentPackageDeps clbi),
IPI.depends = depends,
IPI.abiDepends = abi_depends,
IPI.ccOptions = [], -- Note. NOT ccOptions bi!
-- We don't want cc-options to be propagated
-- to C compilations in other packages.
......@@ -427,6 +436,16 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi
}
where
bi = libBuildInfo lib
--TODO: unclear what the root cause of the
-- duplication is, but we nub it here for now:
depends = ordNub $ map fst (componentPackageDeps clbi)
abi_depends = map add_abi depends
add_abi uid = IPI.AbiDependency uid abi
where
abi = case Index.lookupUnitId (installedPkgs lbi) uid of
Nothing -> error $
"generalInstalledPackageInfo: missing IPI for " ++ display uid
Just ipi -> IPI.abiHash ipi
(absinc, relinc) = partition isAbsolute (includeDirs bi)
hasModules = not $ null (allLibModules lib clbi)
comp = compiler lbi
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment