Commit 1e048986 authored by Edward Z. Yang's avatar Edward Z. Yang
Browse files

Merge pull request #2038 from ezyang/ezyang-renaming

Support module thinning and renaming Cabal-side.

Travis failure is due to https://github.com/haskell/cabal/issues/2114
parents 73cffeec 31719ae9
......@@ -290,6 +290,7 @@ test-suite package-tests
build-depends:
base,
binary >= 0.7 && < 0.8,
containers,
test-framework,
test-framework-quickcheck2 >= 0.2.12,
test-framework-hunit,
......
......@@ -33,6 +33,11 @@ module Distribution.PackageDescription (
BuildType(..),
knownBuildTypes,
-- ** Renaming
ModuleRenaming(..),
defaultRenaming,
lookupRenaming,
-- ** Libraries
Library(..),
ModuleReexport(..),
......@@ -108,11 +113,14 @@ import Control.Monad (MonadPlus(mplus))
import GHC.Generics (Generic)
import Text.PrettyPrint as Disp
import qualified Distribution.Compat.ReadP as Parse
import Distribution.Compat.ReadP ((<++))
import qualified Data.Char as Char (isAlphaNum, isDigit, toLower)
import qualified Data.Map as Map
import Data.Map (Map)
import Distribution.Package
( PackageName(PackageName), PackageIdentifier(PackageIdentifier)
, Dependency, Package(..) )
, Dependency, Package(..), PackageName, packageName )
import Distribution.ModuleName ( ModuleName )
import Distribution.Version
( Version(Version), VersionRange, anyVersion, orLaterVersion
......@@ -284,6 +292,68 @@ instance Text BuildType where
"Make" -> Make
_ -> UnknownBuildType name
-- ---------------------------------------------------------------------------
-- Module renaming
-- | Renaming applied to the modules provided by a package.
-- The boolean indicates whether or not to also include all of the
-- original names of modules. Thus, @ModuleRenaming False []@ is
-- "don't expose any modules, and @ModuleRenaming True [("Data.Bool", "Bool")]@
-- is, "expose all modules, but also expose @Data.Bool@ as @Bool@".
--
data ModuleRenaming = ModuleRenaming Bool [(ModuleName, ModuleName)]
deriving (Show, Read, Eq, Typeable, Data, Generic)
defaultRenaming :: ModuleRenaming
defaultRenaming = ModuleRenaming True []
lookupRenaming :: Package pkg => pkg -> Map PackageName ModuleRenaming -> ModuleRenaming
lookupRenaming pkg rns =
Map.findWithDefault
(error ("lookupRenaming: missing renaming for " ++ display (packageName pkg)))
(packageName pkg) rns
instance Binary ModuleRenaming where
instance Monoid ModuleRenaming where
ModuleRenaming b rns `mappend` ModuleRenaming b' rns'
= ModuleRenaming (b || b') (rns ++ rns') -- ToDo: dedupe?
mempty = ModuleRenaming False []
-- NB: parentheses are mandatory, because later we may extend this syntax
-- to allow "hiding (A, B)" or other modifier words.
instance Text ModuleRenaming where
disp (ModuleRenaming True []) = Disp.empty
disp (ModuleRenaming b vs) = (if b then text "with" else Disp.empty) <+> dispRns
where dispRns = Disp.parens
(Disp.hsep
(Disp.punctuate Disp.comma (map dispEntry vs)))
dispEntry (orig, new)
| orig == new = disp orig
| otherwise = disp orig <+> text "as" <+> disp new
parse = do Parse.string "with" >> Parse.skipSpaces
fmap (ModuleRenaming True) parseRns
<++ fmap (ModuleRenaming False) parseRns
<++ return (ModuleRenaming True [])
where parseRns = do
rns <- Parse.between (Parse.char '(') (Parse.char ')') parseList
Parse.skipSpaces
return rns
parseList =
Parse.sepBy parseEntry (Parse.char ',' >> Parse.skipSpaces)
parseEntry :: Parse.ReadP r (ModuleName, ModuleName)
parseEntry = do
orig <- parse
Parse.skipSpaces
(do _ <- Parse.string "as"
Parse.skipSpaces
new <- parse
Parse.skipSpaces
return (orig, new)
<++
return (orig, orig))
-- ---------------------------------------------------------------------------
-- The Library type
......@@ -707,7 +777,8 @@ data BuildInfo = BuildInfo {
customFieldsBI :: [(String,String)], -- ^Custom fields starting
-- with x-, stored in a
-- simple assoc-list.
targetBuildDepends :: [Dependency] -- ^ Dependencies specific to a library or executable target
targetBuildDepends :: [Dependency], -- ^ Dependencies specific to a library or executable target
targetBuildRenaming :: Map PackageName ModuleRenaming
}
deriving (Generic, Show, Read, Eq, Typeable, Data)
......@@ -739,7 +810,8 @@ instance Monoid BuildInfo where
ghcProfOptions = [],
ghcSharedOptions = [],
customFieldsBI = [],
targetBuildDepends = []
targetBuildDepends = [],
targetBuildRenaming = Map.empty
}
mappend a b = BuildInfo {
buildable = buildable a && buildable b,
......@@ -766,12 +838,14 @@ instance Monoid BuildInfo where
ghcProfOptions = combine ghcProfOptions,
ghcSharedOptions = combine ghcSharedOptions,
customFieldsBI = combine customFieldsBI,
targetBuildDepends = combineNub targetBuildDepends
targetBuildDepends = combineNub targetBuildDepends,
targetBuildRenaming = combineMap targetBuildRenaming
}
where
combine field = field a `mappend` field b
combineNub field = nub (combine field)
combineMby field = field b `mplus` field a
combineMap field = Map.unionWith mappend (field a) (field b)
emptyBuildInfo :: BuildInfo
emptyBuildInfo = mempty
......
......@@ -40,6 +40,7 @@ import Control.Monad
( filterM, liftM )
import qualified System.Directory as System
( doesFileExist, doesDirectoryExist )
import qualified Data.Map as Map
import Distribution.PackageDescription
import Distribution.PackageDescription.Configuration
......@@ -910,6 +911,14 @@ checkCabalVersion pkg =
"To use the 'reexported-module' field the package needs to specify "
++ "at least 'cabal-version: >= 1.21'."
-- check use of thinning and renaming
, checkVersion [1,21] (not (null depsUsingThinningRenamingSyntax)) $
PackageDistInexcusable $
"The package uses thinning and renaming in the 'build-depends' field: "
++ commaSep (map display depsUsingThinningRenamingSyntax)
++ ". To use this new syntax, the package needs to specify at least"
++ "'cabal-version: >= 1.21'."
-- check use of default-extensions field
-- don't need to do the equivalent check for other-extensions
, checkVersion [1,10] (any (not . null) (buildInfoField defaultExtensions)) $
......@@ -1080,6 +1089,14 @@ checkCabalVersion pkg =
depsUsingWildcardSyntax = [ dep | dep@(Dependency _ vr) <- buildDepends pkg
, usesWildcardSyntax vr ]
-- XXX: If the user writes build-depends: foo with (), this is
-- indistinguishable from build-depends: foo, so there won't be an
-- error even though there should be
depsUsingThinningRenamingSyntax = [ name
| bi <- allBuildInfo pkg
, (name, rns) <- Map.toList (targetBuildRenaming bi)
, rns /= ModuleRenaming True [] ]
testedWithUsingWildcardSyntax = [ Dependency (PackageName (display compiler)) vr
| (compiler, vr) <- testedWith pkg
, usesWildcardSyntax vr ]
......
{-# LANGUAGE DeriveDataTypeable #-}
-----------------------------------------------------------------------------
-- |
-- Module : Distribution.PackageDescription.Parse
......@@ -48,11 +49,15 @@ import Control.Applicative (Applicative(..))
import Control.Arrow (first)
import System.Directory (doesFileExist)
import qualified Data.ByteString.Lazy.Char8 as BS.Char8
import Data.Typeable
import Data.Data
import qualified Data.Map as Map
import Distribution.Text
( Text(disp, parse), display, simpleParse )
import Distribution.Compat.ReadP
((+++), option)
import qualified Distribution.Compat.ReadP as Parse
import Text.PrettyPrint
import Distribution.ParseUtils hiding (parseFields)
......@@ -388,6 +393,10 @@ binfoFieldDescrs =
, commaListField "build-tools"
disp parseBuildTool
buildTools (\xs binfo -> binfo{buildTools=xs})
, commaListFieldWithSep vcat "build-depends"
disp parse
buildDependsWithRenaming
setBuildDependsWithRenaming
, spaceListField "cpp-options"
showToken parseTokenQ'
cppOptions (\val binfo -> binfo{cppOptions=val})
......@@ -568,7 +577,7 @@ constraintFieldNames = ["build-depends"]
-- they add and define an accessor that specifies what the dependencies
-- are. This way we would completely reuse the parsing knowledge from the
-- field descriptor.
parseConstraint :: Field -> ParseResult [Dependency]
parseConstraint :: Field -> ParseResult [DependencyWithRenaming]
parseConstraint (F l n v)
| n == "build-depends" = runP l n (parseCommaList parse) v
parseConstraint f = userBug $ "Constraint was expected (got: " ++ show f ++ ")"
......@@ -1005,15 +1014,17 @@ parsePackageDescription file = do
condFlds = [ f | f@IfBlock{} <- allflds ]
sections = [ s | s@Section{} <- allflds ]
let (depFlds, dataFlds) = partition isConstraint simplFlds
-- Put these through the normal parsing pass too, so that we
-- collect the ModRenamings
let depFlds = filter isConstraint simplFlds
mapM_
(\(Section l n _ _) -> lift . warning $
"Unexpected section '" ++ n ++ "' on line " ++ show l)
sections
a <- parser dataFlds
deps <- liftM concat . mapM (lift . parseConstraint) $ depFlds
a <- parser simplFlds
deps <- liftM concat . mapM (lift . fmap (map dependency) . parseConstraint) $ depFlds
ifs <- mapM processIfs condFlds
......@@ -1217,3 +1228,32 @@ findIndentTabs = concatMap checkLine
--test_findIndentTabs = findIndentTabs $ unlines $
-- [ "foo", " bar", " \t baz", "\t biz\t", "\t\t \t mib" ]
-- | Dependencies plus module renamings. This is what users specify; however,
-- renaming information is not used for dependency resolution.
data DependencyWithRenaming = DependencyWithRenaming Dependency ModuleRenaming
deriving (Read, Show, Eq, Typeable, Data)
dependency :: DependencyWithRenaming -> Dependency
dependency (DependencyWithRenaming dep _) = dep
instance Text DependencyWithRenaming where
disp (DependencyWithRenaming d rns) = disp d <+> disp rns
parse = do d <- parse
Parse.skipSpaces
rns <- parse
Parse.skipSpaces
return (DependencyWithRenaming d rns)
buildDependsWithRenaming :: BuildInfo -> [DependencyWithRenaming]
buildDependsWithRenaming pkg =
map (\dep@(Dependency n _) ->
DependencyWithRenaming dep
(Map.findWithDefault defaultRenaming n (targetBuildRenaming pkg)))
(targetBuildDepends pkg)
setBuildDependsWithRenaming :: [DependencyWithRenaming] -> BuildInfo -> BuildInfo
setBuildDependsWithRenaming deps pkg = pkg {
targetBuildDepends = map dependency deps,
targetBuildRenaming = Map.fromList (map (\(DependencyWithRenaming (Dependency n _) rns) -> (n, rns)) deps)
}
......@@ -36,14 +36,14 @@ import qualified Distribution.Simple.Build.PathsModule as Build.PathsModule
import Distribution.Package
( Package(..), PackageName(..), PackageIdentifier(..)
, Dependency(..), thisPackageVersion, mkPackageKey )
, Dependency(..), thisPackageVersion, mkPackageKey, packageName )
import Distribution.Simple.Compiler
( Compiler, CompilerFlavor(..), compilerFlavor
, PackageDB(..), PackageDBStack, packageKeySupported )
import Distribution.PackageDescription
( PackageDescription(..), BuildInfo(..), Library(..), Executable(..)
, TestSuite(..), TestSuiteInterface(..), Benchmark(..)
, BenchmarkInterface(..) )
, BenchmarkInterface(..), defaultRenaming )
import qualified Distribution.InstalledPackageInfo as IPI
import qualified Distribution.ModuleName as ModuleName
import Distribution.ModuleName (ModuleName)
......@@ -80,6 +80,7 @@ import Distribution.Verbosity
import Distribution.Text
( display )
import qualified Data.Map as Map
import Data.Maybe
( maybeToList )
import Data.Either
......@@ -366,6 +367,7 @@ testSuiteLibV09AsLibAndExe pkg_descr
}
libClbi = LibComponentLocalBuildInfo
{ componentPackageDeps = componentPackageDeps clbi
, componentPackageRenaming = componentPackageRenaming clbi
, componentLibraries = [LibraryName (testName test)]
, componentModuleReexports = []
}
......@@ -397,7 +399,10 @@ testSuiteLibV09AsLibAndExe pkg_descr
buildInfo = (testBuildInfo test) {
hsSourceDirs = [ testDir ],
targetBuildDepends = testLibDep
: (targetBuildDepends $ testBuildInfo test)
: (targetBuildDepends $ testBuildInfo test),
targetBuildRenaming =
Map.insert (packageName pkg) defaultRenaming
(targetBuildRenaming $ testBuildInfo test)
}
}
-- | The stub executable needs a new 'ComponentLocalBuildInfo'
......@@ -407,7 +412,10 @@ testSuiteLibV09AsLibAndExe pkg_descr
(IPI.installedPackageId ipi, packageId ipi)
: (filter (\(_, x) -> let PackageName name = pkgName x
in name == "Cabal" || name == "base")
(componentPackageDeps clbi))
(componentPackageDeps clbi)),
componentPackageRenaming =
Map.insert (packageName ipi) defaultRenaming
(componentPackageRenaming clbi)
}
testSuiteLibV09AsLibAndExe _ TestSuite{} _ _ _ _ = error "testSuiteLibV09AsLibAndExe: wrong kind"
......@@ -425,7 +433,8 @@ benchmarkExeV10asExe bm@Benchmark { benchmarkInterface = BenchmarkExeV10 _ f }
buildInfo = benchmarkBuildInfo bm
}
exeClbi = ExeComponentLocalBuildInfo {
componentPackageDeps = componentPackageDeps clbi
componentPackageDeps = componentPackageDeps clbi,
componentPackageRenaming = componentPackageRenaming clbi
}
benchmarkExeV10asExe Benchmark{} _ = error "benchmarkExeV10asExe: wrong kind"
......
......@@ -45,6 +45,7 @@ module Distribution.Simple.Compiler (
unsupportedExtensions,
parmakeSupported,
reexportedModulesSupported,
renamingPackageFlagsSupported,
packageKeySupported
) where
......@@ -207,6 +208,10 @@ parmakeSupported = ghcSupported "Support parallel --make"
reexportedModulesSupported :: Compiler -> Bool
reexportedModulesSupported = ghcSupported "Support reexported-modules"
-- | Does this compiler support thinning/renaming on package flags?
renamingPackageFlagsSupported :: Compiler -> Bool
renamingPackageFlagsSupported = ghcSupported "Support thinning and renaming package flags"
-- | Does this compiler support package keys?
packageKeySupported :: Compiler -> Bool
packageKeySupported = ghcSupported "Uses package keys"
......
......@@ -48,7 +48,7 @@ import Distribution.Simple.Compiler
( CompilerFlavor(..), Compiler(..), compilerFlavor, compilerVersion
, showCompilerId, unsupportedLanguages, unsupportedExtensions
, PackageDB(..), PackageDBStack, reexportedModulesSupported
, packageKeySupported )
, packageKeySupported, renamingPackageFlagsSupported )
import Distribution.Simple.PreProcess ( platformDefines )
import Distribution.Package
( PackageName(PackageName), PackageIdentifier(..), PackageId
......@@ -68,7 +68,7 @@ import Distribution.PackageDescription as PD
, Library(..), hasLibs, Executable(..), BuildInfo(..), allExtensions
, HookedBuildInfo, updatePackageDescription, allBuildInfo
, Flag(flagName), FlagName(..), TestSuite(..), Benchmark(..)
, ModuleReexport(..) )
, ModuleReexport(..) , defaultRenaming )
import Distribution.ModuleName
( ModuleName )
import Distribution.PackageDescription.Configuration
......@@ -419,6 +419,14 @@ configure (pkg_descr0, pbi) cfg
-- we do it here so that those get checked too
let pkg_descr = addExtraIncludeLibDirs pkg_descr0'
unless (renamingPackageFlagsSupported comp ||
and [ rn == defaultRenaming
| bi <- allBuildInfo pkg_descr
, rn <- Map.elems (targetBuildRenaming bi)]) $
die $ "Your compiler does not support thinning and renaming on "
++ "package flags. To use this feature you probably must use "
++ "GHC 7.9 or later."
when (not (null flags)) $
info verbosity $ "Flags chosen: "
++ intercalate ", " [ name ++ "=" ++ display value
......@@ -679,7 +687,7 @@ hackageUrl = "http://hackage.haskell.org/package/"
data ResolvedDependency = ExternalDependency Dependency InstalledPackageInfo
| InternalDependency Dependency PackageId -- should be a
-- lib name
-- lib name
data FailedDependency = DependencyNotExists PackageName
| DependencyNoVersion Dependency
......@@ -1121,19 +1129,23 @@ mkComponentsLocalBuildInfo installedPackages pkg_descr
return LibComponentLocalBuildInfo {
componentPackageDeps = cpds,
componentLibraries = [LibraryName ("HS" ++ display pkg_key)],
componentPackageRenaming = cprns,
componentModuleReexports = reexports
}
CExe _ ->
return ExeComponentLocalBuildInfo {
componentPackageDeps = cpds
componentPackageDeps = cpds,
componentPackageRenaming = cprns
}
CTest _ ->
return TestComponentLocalBuildInfo {
componentPackageDeps = cpds
componentPackageDeps = cpds,
componentPackageRenaming = cprns
}
CBench _ ->
return BenchComponentLocalBuildInfo {
componentPackageDeps = cpds
componentPackageDeps = cpds,
componentPackageRenaming = cprns
}
where
bi = componentBuildInfo component
......@@ -1144,12 +1156,21 @@ mkComponentsLocalBuildInfo installedPackages pkg_descr
| pkgid <- selectSubset bi internalPkgDeps ]
else [ (installedPackageId pkg, packageId pkg)
| pkg <- externalPkgDeps ]
cprns = if newPackageDepsBehaviour pkg_descr
then 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
-- deps were bundled up in buildDepends, we didn't do this for
-- renamings, so it's not even clear how to get the merged
-- version. So just assume that all of them are the default..
else Map.fromList (map (\(_,pid) -> (packageName pid, defaultRenaming)) cpds)
selectSubset :: Package pkg => BuildInfo -> [pkg] -> [pkg]
selectSubset bi pkgs =
[ pkg | pkg <- pkgs, packageName pkg `elem` names ]
where
names = [ name | Dependency name _ <- targetBuildDepends bi ]
[ pkg | pkg <- pkgs, packageName pkg `elem` names bi ]
names bi = [ name | Dependency name _ <- targetBuildDepends bi ]
-- | Given the author-specified re-export declarations from the .cabal file,
-- resolve them to the form that we need for the package database.
......
......@@ -52,7 +52,7 @@ import qualified Distribution.Simple.GHC.IPI642 as IPI642
import Distribution.PackageDescription as PD
( PackageDescription(..), BuildInfo(..), Executable(..)
, Library(..), libModules, exeModules, hcOptions
, usedExtensions, allExtensions )
, usedExtensions, allExtensions, ModuleRenaming, lookupRenaming )
import Distribution.InstalledPackageInfo
( InstalledPackageInfo )
import qualified Distribution.InstalledPackageInfo as InstalledPackageInfo
......@@ -67,7 +67,7 @@ import Distribution.Simple.InstallDirs hiding ( absoluteInstallDirs )
import Distribution.Simple.BuildPaths
import Distribution.Simple.Utils
import Distribution.Package
( PackageName(..) )
( PackageName(..), InstalledPackageId, PackageId )
import qualified Distribution.ModuleName as ModuleName
import Distribution.Simple.Program
( Program(..), ConfiguredProgram(..), ProgramConfiguration
......@@ -658,6 +658,11 @@ substTopDir topDir ipo
where f ('$':'t':'o':'p':'d':'i':'r':rest) = topDir ++ rest
f x = x
mkGhcOptPackages :: ComponentLocalBuildInfo -> [(InstalledPackageId, PackageId, ModuleRenaming)]
mkGhcOptPackages clbi =
map (\(i,p) -> (i,p,lookupRenaming p (componentPackageRenaming clbi)))
(componentPackageDeps clbi)
-- -----------------------------------------------------------------------------
-- Building
......@@ -888,7 +893,7 @@ buildOrReplLib forRepl verbosity numJobsFlag pkg_descr lbi lib clbi = do
ghcOptPackageKey = toFlag (pkgKey lbi),
ghcOptNoAutoLinkPackages = toFlag True,
ghcOptPackageDBs = withPackageDB lbi,
ghcOptPackages = componentPackageDeps clbi,
ghcOptPackages = mkGhcOptPackages clbi ,
ghcOptLinkLibs = extraLibs libBi,
ghcOptLinkLibPath = extraLibDirs libBi
}
......@@ -1187,7 +1192,7 @@ componentGhcOptions verbosity lbi bi clbi odir =
ghcOptHideAllPackages = toFlag True,
ghcOptCabal = toFlag True,
ghcOptPackageDBs = withPackageDB lbi,
ghcOptPackages = componentPackageDeps clbi,
ghcOptPackages = mkGhcOptPackages clbi,
ghcOptSplitObjs = toFlag (splitObjs lbi),
ghcOptSourcePathClear = toFlag True,
ghcOptSourcePath = [odir] ++ nub (hsSourceDirs bi)
......@@ -1226,7 +1231,7 @@ componentCcGhcOptions verbosity lbi bi clbi pref filename =
ghcOptCppIncludePath = [autogenModulesDir lbi, odir]
++ PD.includeDirs bi,
ghcOptPackageDBs = withPackageDB lbi,
ghcOptPackages = componentPackageDeps clbi,
ghcOptPackages = mkGhcOptPackages clbi,
ghcOptCcOptions = (case withOptimization lbi of
NoOptimisation -> []
_ -> ["-O2"]) ++
......
......@@ -65,11 +65,12 @@ import Distribution.Simple.Program (ProgramConfiguration)
import Distribution.PackageDescription
( PackageDescription(..), withLib, Library(libBuildInfo), withExe
, Executable(exeName, buildInfo), withTest, TestSuite(..)
, BuildInfo(buildable), Benchmark(..) )
, BuildInfo(buildable), Benchmark(..), ModuleRenaming(..) )
import qualified Distribution.InstalledPackageInfo as Installed
( ModuleReexport(..) )
import Distribution.Package
( PackageId, Package(..), InstalledPackageId(..), PackageKey )
( PackageId, Package(..), InstalledPackageId(..), PackageKey
, PackageName )
import Distribution.Simple.Compiler
( Compiler(..), PackageDBStack, OptimisationLevel )
import Distribution.Simple.PackageIndex
......@@ -88,6 +89,7 @@ import Data.List (nub, find)
import Data.Maybe
import Data.Tree (flatten)
import GHC.Generics (Generic)
import Data.Map (Map)
-- | Data cached after configuration step. See also
-- 'Distribution.Simple.Setup.ConfigFlags'.
......@@ -193,17 +195,21 @@ data ComponentLocalBuildInfo
-- satisfied in terms of version ranges. This field fixes those dependencies
-- to the specific versions available on this machine for this compiler.
componentPackageDeps :: [(InstalledPackageId, PackageId)],
componentLibraries :: [LibraryName],
componentModuleReexports :: [Installed.ModuleReexport]
componentModuleReexports :: [Installed.ModuleReexport],
componentPackageRenaming :: Map PackageName ModuleRenaming,
componentLibraries :: [LibraryName]
}
| ExeComponentLocalBuildInfo {
componentPackageDeps :: [(InstalledPackageId, PackageId)]
componentPackageDeps :: [(InstalledPackageId, PackageId)],
componentPackageRenaming :: Map PackageName ModuleRenaming
}
| TestComponentLocalBuildInfo {
componentPackageDeps :: [(InstalledPackageId, PackageId)]
componentPackageDeps :: [(InstalledPackageId, PackageId)],
componentPackageRenaming :: Map PackageName ModuleRenaming
}
| BenchComponentLocalBuildInfo {
componentPackageDeps :: [(InstalledPackageId, PackageId)]
componentPackageDeps :: [(InstalledPackageId, PackageId)],
componentPackageRenaming :: Map PackageName ModuleRenaming
}
deriving (Generic, Read, Show)
......
......@@ -12,6 +12,7 @@ module Distribution.Simple.Program.GHC (
) where
import Distribution.Package
import Distribution.PackageDescription hiding (Flag)
import Distribution.ModuleName
import Distribution.Simple.Compiler hiding (Flag)
import Distribution.Simple.Setup ( Flag(..), flagToMaybe, fromFlagOrDefault,
......@@ -76,7 +77,7 @@ data GhcOptions = GhcOptions {
-- | The GHC packages to use. For compatability with old and new ghc, this
-- requires both the short and long form of the package id;
-- the @ghc -package@ or @ghc -package-id@ flags.
ghcOptPackages :: [(InstalledPackageId, PackageId)],
ghcOptPackages :: [(InstalledPackageId, PackageId, ModuleRenaming)],
-- | Start with a clean package set; the @ghc -hide-all-packages@ flag
ghcOptHideAllPackages :: Flag Bool,
......@@ -339,8 +340,10 @@ renderGhcOptions comp opts
, packageDbArgs version (flags ghcOptPackageDBs)
, concat $ if ver >= [6,11]
then [ ["-package-id", display ipkgid] | (ipkgid,_) <- flags ghcOptPackages ]
else [ ["-package", display pkgid] | (_,pkgid) <- flags ghcOptPackages ]
then let space "" = ""
space xs = ' ' : xs
in [ ["-package-id", display ipkgid ++ space (display rns)] | (ipkgid,_,rns) <- flags ghcOptPackages ]
else [ ["-package", display pkgid] | (_,pkgid,_) <- flags ghcOptPackages ]
----------------------------
-- Language and extensions
......
......@@ -1294,6 +1294,23 @@ values for these fields.
It is only syntactic sugar. It is exactly equivalent to `foo >= 1.2 && < 1.3`.
With Cabal 1.20 and GHC 7.10, `build-depends` also supports module
thinning and renaming, which allows you to selectively decide what
modules become visible from a package dependency. For example:
~~~~~~~~~~~~~~~~
build-depends: containers (Data.Set, Data.IntMap as Map)
~~~~~~~~~~~~~~~~
This results in only the modules `Data.Set` and `Map` being visible to
the user from containers, hiding all other modules. To add additional
names for modules without hiding the others, you can use the `with`
keyword:
~~~~~~~~~~~~~~~~
build-depends: containers with (Data.IntMap as Map)
~~~~~~~~~~~~~~~~
Note: Prior to Cabal 1.8, build-depends specified in each section
were global to all sections. This was unintentional, but some packages