Commit 0ef39071 authored by Edward Z. Yang's avatar Edward Z. Yang

Preliminary support for compiling signature files, using --instantiate-with.

There's no chrome here, but some of the guts for Cabal supporting compiling
signatures.  The key UI is a new --instantiate-with flag for ./Setup (no support
cabal-install side!) which properly modifies the package key, calculates extra
hole dependencies for a package, and ensures an appropriately
translated -sig-of is passed to GHC.  The UI here is supremely user-unfriendly:
the intent is that users will use cabal-install to calculate these parameters
for them.

ToDo: Cabal's inconsistency check in ./Setup needs to be adjusted to be
less zealous.
Signed-off-by: default avatarEdward Z. Yang <ezyang@cs.stanford.edu>
parent b293f639
......@@ -87,6 +87,7 @@ data InstalledPackageInfo_ m
-- these parts are required by an installed package only:
exposed :: Bool,
exposedModules :: [ExposedModule],
instantiatedWith :: [(m, OriginalModule)],
hiddenModules :: [m],
trusted :: Bool,
importDirs :: [FilePath],
......@@ -138,6 +139,7 @@ emptyInstalledPackageInfo
exposed = False,
exposedModules = [],
hiddenModules = [],
instantiatedWith = [],
trusted = False,
importDirs = [],
libraryDirs = [],
......@@ -238,6 +240,14 @@ parseInstalledPackageInfo =
parseFieldsFlat (fieldsInstalledPackageInfo ++ deprecatedFieldDescrs)
emptyInstalledPackageInfo
parseInstantiatedWith :: Parse.ReadP r (ModuleName, OriginalModule)
parseInstantiatedWith = do k <- parse
_ <- Parse.char '='
n <- parse
_ <- Parse.char '@'
p <- parse
return (k, OriginalModule p n)
-- -----------------------------------------------------------------------------
-- Pretty-printing
......@@ -250,6 +260,9 @@ showInstalledPackageInfoField = showSingleNamedField fieldsInstalledPackageInfo
showSimpleInstalledPackageInfoField :: String -> Maybe (InstalledPackageInfo -> String)
showSimpleInstalledPackageInfoField = showSimpleSingleNamedField fieldsInstalledPackageInfo
showInstantiatedWith :: (ModuleName, OriginalModule) -> Doc
showInstantiatedWith (k, OriginalModule p m) = disp k <> text "=" <> disp m <> text "@" <> disp p
-- -----------------------------------------------------------------------------
-- Description of the fields, for parsing/printing
......@@ -312,6 +325,9 @@ installedFieldDescrs = [
, listField "hidden-modules"
disp parseModuleNameQ
hiddenModules (\xs pkg -> pkg{hiddenModules=xs})
, listField "instantiated-with"
showInstantiatedWith parseInstantiatedWith
instantiatedWith (\xs pkg -> pkg{instantiatedWith=xs})
, boolField "trusted"
trusted (\val pkg -> pkg{trusted=val})
, listField "import-dirs"
......
......@@ -40,6 +40,7 @@ module Distribution.Package (
PackageInstalled(..),
) where
import Distribution.ModuleName ( ModuleName )
import Distribution.Version
( Version(..), VersionRange, anyVersion, thisVersion
, notThisVersion, simplifyVersionRange )
......@@ -161,14 +162,16 @@ fingerprintPackageKey s (Fingerprint a b) = PackageKey s a b
-- immediate dependencies.
mkPackageKey :: Bool -- are modern style package keys supported?
-> PackageId
-> [PackageKey] -- dependencies
-> [PackageKey] -- dependencies
-> [(ModuleName, (PackageKey, ModuleName))] -- hole instantiations
-> PackageKey
mkPackageKey True pid deps = fingerprintPackageKey stubName
. fingerprintString
. ((show pid ++ "\n") ++)
$ show (sort deps)
mkPackageKey True pid deps holes = fingerprintPackageKey stubName
. fingerprintString
. ((show pid ++ "\n") ++)
. ((show (sort holes) ++ "\n") ++)
$ show (sort deps)
where stubName = take 5 (filter (/= '-') (unPackageName (pkgName pid)))
mkPackageKey False pid _ = OldPackageKey pid
mkPackageKey False pid _ _ = OldPackageKey pid
-- The base-62 code is based off of 'locators'
-- ((c) Operational Dynamics Consulting, BSD3 licensed)
......
......@@ -45,6 +45,7 @@ module Distribution.PackageDescription (
withLib,
hasLibs,
libModules,
objectModules,
-- ** Executables
Executable(..),
......@@ -360,6 +361,8 @@ instance Text ModuleRenaming where
data Library = Library {
exposedModules :: [ModuleName],
reexportedModules :: [ModuleReexport],
requiredSignatures:: [ModuleName], -- ^ What sigs need implementations?
exposedSignatures:: [ModuleName], -- ^ What sigs are visible to users?
libExposed :: Bool, -- ^ Is the lib to be exposed by default?
libBuildInfo :: BuildInfo
}
......@@ -371,12 +374,16 @@ instance Monoid Library where
mempty = Library {
exposedModules = mempty,
reexportedModules = mempty,
requiredSignatures = mempty,
exposedSignatures = mempty,
libExposed = True,
libBuildInfo = mempty
}
mappend a b = Library {
exposedModules = combine exposedModules,
reexportedModules = combine reexportedModules,
requiredSignatures = combine requiredSignatures,
exposedSignatures = combine exposedSignatures,
libExposed = libExposed a && libExposed b, -- so False propagates
libBuildInfo = combine libBuildInfo
}
......@@ -408,6 +415,14 @@ withLib pkg_descr f =
libModules :: Library -> [ModuleName]
libModules lib = exposedModules lib
++ otherModules (libBuildInfo lib)
++ exposedSignatures lib
++ requiredSignatures lib
-- | Get all the module names from the library which have OBJECT code.
-- This excludes signatures, which have interface files but no object code.
objectModules :: Library -> [ModuleName]
objectModules lib = exposedModules lib
++ otherModules (libBuildInfo lib)
-- -----------------------------------------------------------------------------
-- Module re-exports
......
......@@ -215,16 +215,32 @@ checkSanity pkg =
duplicateNames = dups $ exeNames ++ testNames ++ bmNames
checkLibrary :: PackageDescription -> Library -> [PackageCheck]
checkLibrary _pkg lib =
checkLibrary pkg lib =
catMaybes [
check (not (null moduleDuplicates)) $
PackageBuildImpossible $
"Duplicate modules in library: "
++ commaSep (map display moduleDuplicates)
-- check use of required-signatures/exposed-signatures sections
, checkVersion [1,21] (not (null (requiredSignatures lib))) $
PackageDistInexcusable $
"To use the 'required-signatures' field the package needs to specify "
++ "at least 'cabal-version: >= 1.21'."
, checkVersion [1,21] (not (null (exposedSignatures lib))) $
PackageDistInexcusable $
"To use the 'exposed-signatures' field the package needs to specify "
++ "at least 'cabal-version: >= 1.21'."
]
where
checkVersion :: [Int] -> Bool -> PackageCheck -> Maybe PackageCheck
checkVersion ver cond pc
| specVersion pkg >= Version ver [] = Nothing
| otherwise = check cond pc
moduleDuplicates = dups (libModules lib ++
map moduleReexportName (reexportedModules lib))
......
......@@ -186,6 +186,12 @@ libFieldDescrs =
, commaListFieldWithSep vcat "reexported-modules" disp parse
reexportedModules (\mods lib -> lib{reexportedModules=mods})
, listFieldWithSep vcat "required-signatures" disp parseModuleNameQ
requiredSignatures (\mods lib -> lib{requiredSignatures=mods})
, listFieldWithSep vcat "exposed-signatures" disp parseModuleNameQ
exposedSignatures (\mods lib -> lib{exposedSignatures=mods})
, boolField "exposed"
libExposed (\val lib -> lib{libExposed=val})
] ++ map biToLib binfoFieldDescrs
......
......@@ -43,7 +43,7 @@ import Distribution.Compiler (CompilerFlavor, parseCompilerFlavorCompat)
import Distribution.License
import Distribution.Version
( Version(..), VersionRange, anyVersion )
import Distribution.Package ( PackageName(..), Dependency(..) )
import Distribution.Package ( PackageName(..), Dependency(..), InstalledPackageId )
import Distribution.ModuleName (ModuleName)
import Distribution.Compat.ReadP as ReadP hiding (get)
import Distribution.ReadE
......
......@@ -360,6 +360,8 @@ testSuiteLibV09AsLibAndExe pkg_descr
lib = Library {
exposedModules = [ m ],
reexportedModules = [],
requiredSignatures = [],
exposedSignatures = [],
libExposed = True,
libBuildInfo = bi
}
......@@ -384,7 +386,7 @@ testSuiteLibV09AsLibAndExe pkg_descr
-- can define multiple actual packages.
lbi' = lbi {
pkgKey = mkPackageKey (packageKeySupported (compiler lbi))
(package pkg) []
(package pkg) [] []
}
ipkgid = inplacePackageId (packageId pkg)
ipi = inplaceInstalledPackageInfo pwd distPref pkg ipkgid lib lbi libClbi
......
......@@ -57,10 +57,8 @@ import Distribution.Package
, Dependency(Dependency), simplifyDependency
, InstalledPackageId(..), thisPackageVersion
, mkPackageKey, PackageKey(..) )
import Distribution.InstalledPackageInfo as Installed
( InstalledPackageInfo, InstalledPackageInfo_(..)
, emptyInstalledPackageInfo )
import qualified Distribution.InstalledPackageInfo as Installed
import Distribution.InstalledPackageInfo (InstalledPackageInfo, emptyInstalledPackageInfo)
import qualified Distribution.Simple.PackageIndex as PackageIndex
import Distribution.Simple.PackageIndex (InstalledPackageIndex)
import Distribution.PackageDescription as PD
......@@ -127,11 +125,11 @@ import Data.Maybe
( isNothing, catMaybes, fromMaybe )
import Data.Either
( partitionEithers )
import qualified Data.Set as Set
import Data.Monoid
( Monoid(..) )
import qualified Data.Map as Map
import Data.Map (Map)
import qualified Data.Set as Set
import Data.Traversable
( mapM )
import System.Directory
......@@ -438,6 +436,9 @@ configure (pkg_descr0, pbi) cfg
checkPackageProblems verbosity pkg_descr0
(updatePackageDescription pbi pkg_descr)
-- Handle hole instantiation
(holeDeps, hole_insts) <- configureInstantiateWith pkg_descr cfg installedPackageSet
let selectDependencies :: [Dependency] ->
([FailedDependency], [ResolvedDependency])
selectDependencies =
......@@ -464,9 +465,14 @@ configure (pkg_descr0, pbi) cfg
reportFailedDependencies failedDeps
reportSelectedDependencies verbosity allPkgDeps
let installDeps = Map.elems
. Map.fromList
. map (\v -> (Installed.installedPackageId v, v))
$ externalPkgDeps ++ holeDeps
packageDependsIndex <-
case PackageIndex.dependencyClosure installedPackageSet
(map Installed.installedPackageId externalPkgDeps) of
(map Installed.installedPackageId installDeps) of
Left packageDependsIndex -> return packageDependsIndex
Right broken ->
die $ "The following installed packages are broken because other"
......@@ -483,7 +489,7 @@ configure (pkg_descr0, pbi) cfg
InstalledPackageId (display (packageId pkg_descr)),
Installed.sourcePackageId = packageId pkg_descr,
Installed.depends =
map Installed.installedPackageId externalPkgDeps
map Installed.installedPackageId installDeps
}
case PackageIndex.dependencyInconsistencies
. PackageIndex.insert pseudoTopPkg
......@@ -501,9 +507,11 @@ configure (pkg_descr0, pbi) cfg
-- Calculate the package key. We're going to store it in LocalBuildInfo
-- canonically, but ComponentsLocalBuildInfo also needs to know about it
-- XXX Do we need the internal deps?
-- NB: does *not* include holeDeps!
let pkg_key = mkPackageKey (packageKeySupported comp)
(package pkg_descr)
(map packageKey externalPkgDeps)
(map Installed.packageKey externalPkgDeps)
(map (\(k,(p,m)) -> (k,(Installed.packageKey p,m))) hole_insts)
-- internal component graph
buildComponents <-
......@@ -511,7 +519,8 @@ configure (pkg_descr0, pbi) cfg
Left componentCycle -> reportComponentCycle componentCycle
Right components ->
case mkComponentsLocalBuildInfo packageDependsIndex pkg_descr
internalPkgDeps externalPkgDeps
internalPkgDeps externalPkgDeps holeDeps
(Map.fromList hole_insts)
pkg_key components of
Left problems -> reportModuleReexportProblems problems
Right components' -> return components'
......@@ -606,6 +615,7 @@ configure (pkg_descr0, pbi) cfg
pkgDescrFile = Nothing,
localPkgDescr = pkg_descr',
pkgKey = pkg_key,
instantiatedWith = hole_insts,
withPrograms = programsConfig''',
withVanillaLib = fromFlag $ configVanillaLib cfg,
withProfLib = fromFlag $ configProfLib cfg,
......@@ -898,6 +908,58 @@ combinedConstraints constraints dependencies installedPackages = do
<> quotes (disp pkgname <> char '=' <> disp ipkgid)
| (pkgname, ipkgid) <- deps ]
-- -----------------------------------------------------------------------------
-- Configuring hole instantiation
configureInstantiateWith :: PackageDescription
-> ConfigFlags
-> InstalledPackageIndex -- ^ installed packages
-> IO ([InstalledPackageInfo],
[(ModuleName, (InstalledPackageInfo, ModuleName))])
configureInstantiateWith pkg_descr cfg installedPackageSet = do
-- Holes: First, check and make sure the provided instantiation covers
-- all the holes we know about. Indefinite package installation is
-- not handled at all at this point.
-- NB: We union together /all/ of the requirements when calculating
-- the package key.
-- NB: For now, we assume that dependencies don't contribute signatures.
-- This will be handled by cabal-install; as far as ./Setup is
-- concerned, the most important thing is to be provided correctly
-- built dependencies.
let signatures =
maybe [] (\lib -> requiredSignatures lib ++ exposedSignatures lib)
(PD.library pkg_descr)
signatureSet = Set.fromList signatures
instantiateMap = Map.fromList (configInstantiateWith cfg)
missing_impls = filter (not . flip Map.member instantiateMap) signatures
hole_insts0 = filter (\(k,_) -> Set.member k signatureSet) (configInstantiateWith cfg)
when (not (null missing_impls)) $
die $ "Missing signature implementations for these modules: "
++ intercalate ", " (map display missing_impls)
-- Holes: Next, we need to make sure we have packages to actually
-- provide the implementations we're talking about. This is on top
-- of the normal dependency resolution process.
-- TODO: internal dependencies (e.g. the test package depending on the
-- main library) is not currently supported
let selectHoleDependency (k,(i,m)) =
case PackageIndex.lookupInstalledPackageId installedPackageSet i of
Just pkginst -> Right (k,(pkginst, m))
Nothing -> Left i
(failed_hmap, hole_insts) = partitionEithers (map selectHoleDependency hole_insts0)
holeDeps = map (fst.snd) hole_insts -- could have dups
-- Holes: Finally, any dependencies selected this way have to be
-- included in the allPkgs index, as well as the buildComponents.
-- But don't report these as potential inconsistencies!
when (not (null failed_hmap)) $
die $ "Could not resolve these package IDs (from signature implementations): "
++ intercalate ", " (map display failed_hmap)
return (holeDeps, hole_insts)
-- -----------------------------------------------------------------------------
-- Configuring program dependencies
......@@ -1107,14 +1169,18 @@ reportComponentCycle cnames =
mkComponentsLocalBuildInfo :: InstalledPackageIndex
-> PackageDescription
-> [PackageId] -> [InstalledPackageInfo]
-> [PackageId] -- internal package deps
-> [InstalledPackageInfo] -- external package deps
-> [InstalledPackageInfo] -- hole package deps
-> Map ModuleName (InstalledPackageInfo, ModuleName)
-> PackageKey
-> [(Component, [ComponentName])]
-> Either [(ModuleReexport, String)] -- errors
[(ComponentName, ComponentLocalBuildInfo,
[ComponentName])] -- ok
mkComponentsLocalBuildInfo installedPackages pkg_descr
internalPkgDeps externalPkgDeps pkg_key graph =
internalPkgDeps externalPkgDeps holePkgDeps hole_insts
pkg_key graph =
sequence
[ do clbi <- componentLocalBuildInfo c
return (componentName c, clbi, cdeps)
......@@ -1128,7 +1194,13 @@ mkComponentsLocalBuildInfo installedPackages pkg_descr
componentLocalBuildInfo component =
case component of
CLib lib -> do
let exports = map (\n -> Installed.ExposedModule n Nothing Nothing) (PD.exposedModules lib)
let exports = map (\n -> Installed.ExposedModule n Nothing Nothing)
(PD.exposedModules lib)
esigs = map (\n -> Installed.ExposedModule n Nothing
(fmap (\(pkg,m) -> Installed.OriginalModule
(Installed.installedPackageId pkg) m)
(Map.lookup n hole_insts)))
(PD.exposedSignatures lib)
reexports <- resolveModuleReexports installedPackages
(packageId pkg_descr)
externalPkgDeps lib
......@@ -1136,7 +1208,7 @@ mkComponentsLocalBuildInfo installedPackages pkg_descr
componentPackageDeps = cpds,
componentLibraries = [LibraryName ("HS" ++ display pkg_key)],
componentPackageRenaming = cprns,
componentExposedModules = exports ++ reexports
componentExposedModules = exports ++ reexports ++ esigs
}
CExe _ ->
return ExeComponentLocalBuildInfo {
......@@ -1155,15 +1227,25 @@ mkComponentsLocalBuildInfo installedPackages pkg_descr
}
where
bi = componentBuildInfo component
dedup = Map.toList . Map.fromList
cpds = if newPackageDepsBehaviour pkg_descr
then [ (installedPackageId pkg, packageId pkg)
then dedup $
[ (Installed.installedPackageId pkg, packageId pkg)
| pkg <- selectSubset bi externalPkgDeps ]
++ [ (inplacePackageId pkgid, pkgid)
| pkgid <- selectSubset bi internalPkgDeps ]
else [ (installedPackageId pkg, packageId pkg)
++ [ (Installed.installedPackageId pkg, packageId pkg)
| pkg <- holePkgDeps ]
else [ (Installed.installedPackageId pkg, packageId pkg)
| pkg <- externalPkgDeps ]
cprns = if newPackageDepsBehaviour pkg_descr
then targetBuildRenaming bi
then Map.unionWith mappend
-- We need hole dependencies passed to GHC, so add them here
-- (but note that they're fully thinned out. If they
-- appeared legitimately the monoid instance will
-- fill them out.
(Map.fromList [(packageName pkg, mempty) | pkg <- holePkgDeps])
(targetBuildRenaming bi)
-- Hack: if we have old package-deps behavior, it's impossible
-- for non-default renamings to be used, because the Cabal
-- version is too early. This is a good, because while all the
......@@ -1207,9 +1289,9 @@ resolveModuleReexports installedPackages srcpkgid externalPkgDeps lib =
exposedModule)])
-- The package index here contains all the indirect deps of the
-- package we're configuring, but we want just the direct deps
| let directDeps = Set.fromList (map installedPackageId externalPkgDeps)
| let directDeps = Set.fromList (map Installed.installedPackageId externalPkgDeps)
, pkg <- PackageIndex.allPackages installedPackages
, installedPackageId pkg `Set.member` directDeps
, Installed.installedPackageId pkg `Set.member` directDeps
, let exportingPackageName = packageName pkg
, exposedModule <- visibleModuleDetails pkg
]
......@@ -1239,7 +1321,7 @@ resolveModuleReexports installedPackages srcpkgid externalPkgDeps lib =
-- The first case is the modules actually defined in this package.
-- In this case the reexport will point to this package.
Nothing -> return exposedModule { Installed.exposedReexport =
Just (Installed.OriginalModule (installedPackageId pkg)
Just (Installed.OriginalModule (Installed.installedPackageId pkg)
(Installed.exposedName exposedModule)) }
-- On the other hand, a visible module might actually be itself
-- a re-export! In this case, the re-export info for the package
......
......@@ -51,7 +51,7 @@ import qualified Distribution.Simple.GHC.IPI641 as IPI641
import qualified Distribution.Simple.GHC.IPI642 as IPI642
import Distribution.PackageDescription as PD
( PackageDescription(..), BuildInfo(..), Executable(..)
, Library(..), libModules, exeModules, hcOptions
, Library(..), libModules, objectModules, exeModules, hcOptions
, usedExtensions, allExtensions, ModuleRenaming, lookupRenaming )
import Distribution.InstalledPackageInfo
( InstalledPackageInfo )
......@@ -697,6 +697,7 @@ buildOrReplLib forRepl verbosity numJobs pkg_descr lbi lib clbi = do
comp = compiler lbi
ghcVersion = compilerVersion comp
(Platform _hostArch hostOS) = hostPlatform lbi
hole_insts = map (\(k,(p,n)) -> (k,(InstalledPackageInfo.packageKey p,n))) (instantiatedWith lbi)
(ghcProg, _) <- requireProgram verbosity ghcProgram (withPrograms lbi)
let runGhcProg = runGHC verbosity ghcProg comp
......@@ -731,6 +732,7 @@ buildOrReplLib forRepl verbosity numJobs pkg_descr lbi lib clbi = do
ghcOptMode = toFlag GhcModeMake,
ghcOptNumJobs = numJobs,
ghcOptPackageKey = toFlag (pkgKey lbi),
ghcOptSigOf = hole_insts,
ghcOptInputModules = toNubListR $ libModules lib
}
......@@ -1134,7 +1136,7 @@ getHaskellObjects lib lbi pref wanted_obj_ext allow_split_objs
then "_split"
else "_" ++ wanted_obj_ext ++ "_split"
dirs = [ pref </> (ModuleName.toFilePath x ++ splitSuffix)
| x <- libModules lib ]
| x <- objectModules lib ]
objss <- mapM getDirectoryContents dirs
let objs = [ dir </> obj
| (objs',dir) <- zip objss dirs, obj <- objs',
......@@ -1143,7 +1145,7 @@ getHaskellObjects lib lbi pref wanted_obj_ext allow_split_objs
return objs
| otherwise =
return [ pref </> ModuleName.toFilePath x <.> wanted_obj_ext
| x <- libModules lib ]
| x <- objectModules lib ]
-- | Extracts a String representing a hash of the ABI of a built
-- library. It can fail if the library has not yet been built.
......
......@@ -84,6 +84,7 @@ toCurrent ipi@InstalledPackageInfo{} =
Current.category = category ipi,
Current.exposed = exposed ipi,
Current.exposedModules = map (mkExposedModule . convertModuleName) (exposedModules ipi),
Current.instantiatedWith = [],
Current.hiddenModules = map convertModuleName (hiddenModules ipi),
Current.trusted = Current.trusted Current.emptyInstalledPackageInfo,
Current.importDirs = importDirs ipi,
......
......@@ -120,6 +120,7 @@ toCurrent ipi@InstalledPackageInfo{} =
Current.exposed = exposed ipi,
Current.exposedModules = map (mkExposedModule . convertModuleName) (exposedModules ipi),
Current.hiddenModules = map convertModuleName (hiddenModules ipi),
Current.instantiatedWith = [],
Current.trusted = Current.trusted Current.emptyInstalledPackageInfo,
Current.importDirs = importDirs ipi,
Current.libraryDirs = libraryDirs ipi,
......
......@@ -62,6 +62,7 @@ import Distribution.Simple.InstallDirs hiding (absoluteInstallDirs,
substPathTemplate, )
import qualified Distribution.Simple.InstallDirs as InstallDirs
import Distribution.Simple.Program (ProgramConfiguration)
import Distribution.InstalledPackageInfo (InstalledPackageInfo)
import Distribution.PackageDescription
( PackageDescription(..), withLib, Library(libBuildInfo), withExe
, Executable(exeName, buildInfo), withTest, TestSuite(..)
......@@ -74,6 +75,7 @@ import Distribution.Simple.Compiler
( Compiler(..), PackageDBStack, OptimisationLevel )
import Distribution.Simple.PackageIndex
( InstalledPackageIndex )
import Distribution.ModuleName ( ModuleName )
import Distribution.Simple.Setup
( ConfigFlags )
import Distribution.Text
......@@ -123,6 +125,7 @@ data LocalBuildInfo = LocalBuildInfo {
pkgKey :: PackageKey,
-- ^ The package key for the current build, calculated from
-- the package ID and the dependency graph.
instantiatedWith :: [(ModuleName, (InstalledPackageInfo, ModuleName))],
withPrograms :: ProgramConfiguration, -- ^Location and args for all programs
withPackageDB :: PackageDBStack, -- ^What package database to use, global\/user
withVanillaLib:: Bool, -- ^Whether to build normal libs.
......
......@@ -192,7 +192,7 @@ preprocessComponent pd comp lbi isSrcDist verbosity handlers = case comp of
BenchmarkUnsupported tt -> die $ "No support for preprocessing benchmark "
++ "type " ++ display tt
where
builtinHaskellSuffixes = ["hs", "lhs"]
builtinHaskellSuffixes = ["hs", "lhs", "hsig", "lhsig"]
builtinCSuffixes = cSourceExtensions
builtinSuffixes = builtinHaskellSuffixes ++ builtinCSuffixes
localHandlers bi = [(ext, h bi lbi) | (ext, h) <- handlers]
......
......@@ -27,6 +27,7 @@ import Language.Haskell.Extension ( Language(..), Extension(..) )
import qualified Data.Map as M
import Data.Monoid
import Data.List ( intercalate )
-- | A structured set of GHC options/flags
--
......@@ -89,6 +90,9 @@ data GhcOptions = GhcOptions {
-- -no-auto-link-packages@ flag.
ghcOptNoAutoLinkPackages :: Flag Bool,
-- | What packages are implementing the signatures
ghcOptSigOf :: [(ModuleName, (PackageKey, ModuleName))],
-----------------
-- Linker stuff
......@@ -346,6 +350,15 @@ renderGhcOptions comp opts
, packageDbArgs version (ghcOptPackageDBs opts)
, if null (ghcOptSigOf opts)
then []
else "-sig-of"
: intercalate "," (map (\(n,(p,m)) -> display n ++ " is "
++ display p ++ ":"
++ display m)
(ghcOptSigOf opts))
: []
, concat $ if ver >= [6,11]
then let space "" = ""
space xs = ' ' : xs
......@@ -442,6 +455,7 @@ instance Monoid GhcOptions where
ghcOptPackages = mempty,
ghcOptHideAllPackages = mempty,
ghcOptNoAutoLinkPackages = mempty,
ghcOptSigOf = mempty,
ghcOptLinkLibs = mempty,
ghcOptLinkLibPath = mempty,
ghcOptLinkOptions = mempty,
......@@ -492,6 +506,7 @@ instance Monoid GhcOptions where
ghcOptPackages = combine ghcOptPackages,
ghcOptHideAllPackages = combine ghcOptHideAllPackages,
ghcOptNoAutoLinkPackages = combine ghcOptNoAutoLinkPackages,
ghcOptSigOf = combine ghcOptSigOf,
ghcOptLinkLibs = combine ghcOptLinkLibs,
ghcOptLinkLibPath = combine ghcOptLinkLibPath,
ghcOptLinkOptions = combine ghcOptLinkOptions,
......
......@@ -274,6 +274,9 @@ generalInstalledPackageInfo adjustRelIncDirs pkg ipid lib lbi clbi installDirs =
IPI.exposed = libExposed lib,
IPI.exposedModules = map fixupSelf (componentExposedModules clbi),
IPI.hiddenModules = otherModules bi,
IPI.instantiatedWith = map (\(k,(p,n)) ->
(k,IPI.OriginalModule (IPI.installedPackageId p) n))
(instantiatedWith lbi),
IPI.trusted = IPI.trusted IPI.emptyInstalledPackageInfo,
IPI.importDirs = [ libdir installDirs | hasModules ],
-- Note. the libsubdir and datasubdir templates have already been expanded
......
......@@ -72,6 +72,7 @@ import Distribution.Text