diff --git a/Cabal/Distribution/PackageDescription/FieldGrammar.hs b/Cabal/Distribution/PackageDescription/FieldGrammar.hs index c00c707e798..578883824f7 100644 --- a/Cabal/Distribution/PackageDescription/FieldGrammar.hs +++ b/Cabal/Distribution/PackageDescription/FieldGrammar.hs @@ -375,6 +375,7 @@ buildInfoFieldGrammar = BuildInfo <*> monoidalFieldAla "js-sources" (alaList' VCat FilePathNT) L.jsSources <*> hsSourceDirsGrammar <*> monoidalFieldAla "other-modules" (alaList' VCat MQuoted) L.otherModules + <*> monoidalFieldAla "virtual-modules" (alaList' VCat MQuoted) L.virtualModules <*> monoidalFieldAla "autogen-modules" (alaList' VCat MQuoted) L.autogenModules <*> optionalFieldAla "default-language" MQuoted L.defaultLanguage <*> monoidalFieldAla "other-languages" (alaList' FSep MQuoted) L.otherLanguages diff --git a/Cabal/Distribution/PackageDescription/Parse.hs b/Cabal/Distribution/PackageDescription/Parse.hs index f6648ad343e..565fca9d74e 100644 --- a/Cabal/Distribution/PackageDescription/Parse.hs +++ b/Cabal/Distribution/PackageDescription/Parse.hs @@ -523,6 +523,9 @@ binfoFieldDescrs = , listFieldWithSep vcat "other-modules" disp parseModuleNameQ otherModules (\val binfo -> binfo{otherModules=val}) + , listFieldWithSep vcat "virtual-modules" + disp parseModuleNameQ + virtualModules (\val binfo -> binfo{virtualModules=val}) , listFieldWithSep vcat "autogen-modules" disp parseModuleNameQ autogenModules (\val binfo -> binfo{autogenModules=val}) diff --git a/Cabal/Distribution/Simple/Register.hs b/Cabal/Distribution/Simple/Register.hs index e66c12179d1..828de049e1b 100644 --- a/Cabal/Distribution/Simple/Register.hs +++ b/Cabal/Distribution/Simple/Register.hs @@ -420,7 +420,10 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi IPI.abiHash = abi_hash, IPI.indefinite = componentIsIndefinite clbi, IPI.exposed = libExposed lib, - IPI.exposedModules = componentExposedModules clbi, + IPI.exposedModules = componentExposedModules clbi + -- add virtual modules into the list of exposed modules for the + -- package database as well. + ++ map (\name -> IPI.ExposedModule name Nothing) (virtualModules bi), IPI.hiddenModules = otherModules bi, IPI.trusted = IPI.trusted IPI.emptyInstalledPackageInfo, IPI.importDirs = [ libdir installDirs | hasModules ], diff --git a/Cabal/Distribution/Types/BuildInfo.hs b/Cabal/Distribution/Types/BuildInfo.hs index a735b55893d..cd9021cf367 100644 --- a/Cabal/Distribution/Types/BuildInfo.hs +++ b/Cabal/Distribution/Types/BuildInfo.hs @@ -66,6 +66,7 @@ data BuildInfo = BuildInfo { jsSources :: [FilePath], hsSourceDirs :: [FilePath], -- ^ where to look for the Haskell module hierarchy otherModules :: [ModuleName], -- ^ non-exposed or non-main modules + virtualModules :: [ModuleName], -- ^ exposed modules that do not have a source file (e.g. @GHC.Prim@ from @ghc-prim@ package) autogenModules :: [ModuleName], -- ^ not present on sdist, Paths_* or user-generated with a custom Setup.hs defaultLanguage :: Maybe Language,-- ^ language used when not explicitly specified @@ -126,6 +127,7 @@ instance Monoid BuildInfo where jsSources = [], hsSourceDirs = [], otherModules = [], + virtualModules = [], autogenModules = [], defaultLanguage = Nothing, otherLanguages = [], @@ -171,6 +173,7 @@ instance Semigroup BuildInfo where jsSources = combineNub jsSources, hsSourceDirs = combineNub hsSourceDirs, otherModules = combineNub otherModules, + virtualModules = combineNub virtualModules, autogenModules = combineNub autogenModules, defaultLanguage = combineMby defaultLanguage, otherLanguages = combineNub otherLanguages, diff --git a/Cabal/Distribution/Types/BuildInfo/Lens.hs b/Cabal/Distribution/Types/BuildInfo/Lens.hs index 43b5bd5795c..fc13524427d 100644 --- a/Cabal/Distribution/Types/BuildInfo/Lens.hs +++ b/Cabal/Distribution/Types/BuildInfo/Lens.hs @@ -99,6 +99,10 @@ class HasBuildInfo a where otherModules = buildInfo . otherModules {-# INLINE otherModules #-} + virtualModules :: Lens' a [ModuleName] + virtualModules = buildInfo . virtualModules + {-# INLINE virtualModules #-} + autogenModules :: Lens' a [ModuleName] autogenModules = buildInfo . autogenModules {-# INLINE autogenModules #-} @@ -245,6 +249,9 @@ instance HasBuildInfo BuildInfo where otherModules f s = fmap (\x -> s { T.otherModules = x }) (f (T.otherModules s)) {-# INLINE otherModules #-} + virtualModules f s = fmap (\x -> s { T.virtualModules = x }) (f (T.virtualModules s)) + {-# INLINE virtualModules #-} + autogenModules f s = fmap (\x -> s { T.autogenModules = x }) (f (T.autogenModules s)) {-# INLINE autogenModules #-} diff --git a/Cabal/changelog b/Cabal/changelog index b8411e2f305..d998f01ab4e 100644 --- a/Cabal/changelog +++ b/Cabal/changelog @@ -1,6 +1,8 @@ -*-change-log-*- 2.2.0.0 (current development version) + * Added `virtual-module` field, to allow modules that are not built + but registered (#4875). * `copyComponent` and `installIncludeFiles` will look for include headers in the build directory ('dist/build/...' by default) as well (#4866). diff --git a/Cabal/doc/developing-packages.rst b/Cabal/doc/developing-packages.rst index 92b715c099d..57b9a2d8776 100644 --- a/Cabal/doc/developing-packages.rst +++ b/Cabal/doc/developing-packages.rst @@ -1010,6 +1010,15 @@ The library section should contain the following fields: A list of modules added by this package. +.. pkg-field:: virtual-modules: identifier list + + A list of virtual modules provided by this package. Virtual modules + are modules without a source file. See for example the ``GHC.Prim`` + module from the ``ghc-prim`` package. Modules listed here will not be + built, but still end up in the list of ``exposed-modules`` in the + installed package info when the package is registered in the package + database. + .. pkg-field:: exposed: boolean :default: ``True``