From 7c1ce92cff2bf03d073c82c7efa210cb3b45e0f3 Mon Sep 17 00:00:00 2001 From: Gautier DI FOLCO Date: Sat, 15 Oct 2022 17:40:51 +0200 Subject: [PATCH] Add PackageInfos_ (#3909) --- Cabal/Cabal.cabal | 2 + .../Distribution/PackageDescription/Check.hs | 45 ++++++++++++-- Cabal/src/Distribution/Simple/Build.hs | 10 +++- .../Simple/Build/PackageInfoModule.hs | 56 +++++++++++++++++ .../Simple/Build/PackageInfoModule/Z.hs | 60 +++++++++++++++++++ Cabal/src/Distribution/Simple/BuildPaths.hs | 9 +++ Cabal/src/Distribution/Simple/SrcDist.hs | 2 + .../AutogenModules/Package/my.cabal | 4 ++ .../AutogenModules/Package/setup.cabal.out | 1 + .../AutogenModules/Package/setup.out | 1 + .../SrcDist/AutogenModules.cabal | 8 +++ .../AutogenModules/SrcDist/setup.test.hs | 8 +-- .../CabalVersion/AutoGenMods/cabal.out | 1 + .../CabalVersion/AutoGenMods/pkg.cabal | 4 +- .../NonConfCheck/PathsExtensions/cabal.out | 1 + .../NonConfCheck/PathsExtensions/pkg.cabal | 8 ++- .../NewBuild/CmdRun/Datafiles/foo/foo.cabal | 4 +- .../NewBuild/T5164/setup-lib/setup-lib.cabal | 4 +- .../PackageInfoModule/Executable/Main.hs | 7 +++ .../PackageInfoModule/Executable/my.cabal | 18 ++++++ .../Executable/setup.cabal.out | 5 ++ .../PackageInfoModule/Executable/setup.out | 5 ++ .../Executable/setup.test.hs | 4 ++ .../ImportQualifiedPost/Main.hs | 4 ++ .../ImportQualifiedPost/my.cabal | 19 ++++++ .../ImportQualifiedPost/setup.cabal.out | 5 ++ .../ImportQualifiedPost/setup.out | 5 ++ .../ImportQualifiedPost/setup.test.hs | 4 ++ .../PackageInfoModule/Library/my.cabal | 36 +++++++++++ .../PackageInfoModule/Library/setup.cabal.out | 5 ++ .../PackageInfoModule/Library/setup.out | 5 ++ .../PackageInfoModule/Library/setup.test.hs | 3 + .../Executable-Relocatable/my.cabal | 4 +- .../PathsModule/Executable/my.cabal | 4 +- .../PathsModule/ImportQualifiedPost/my.cabal | 4 +- .../PackageTests/PathsModule/Library/my.cabal | 4 +- .../MissingSafeHaskellMode/my.cabal | 4 +- changelog.d/pr-8534 | 10 ++++ doc/cabal-package.rst | 23 ++++++- 39 files changed, 382 insertions(+), 24 deletions(-) create mode 100644 Cabal/src/Distribution/Simple/Build/PackageInfoModule.hs create mode 100644 Cabal/src/Distribution/Simple/Build/PackageInfoModule/Z.hs create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/Executable/Main.hs create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/Executable/my.cabal create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.cabal.out create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.out create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.test.hs create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/Main.hs create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/my.cabal create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.cabal.out create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.out create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.test.hs create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/Library/my.cabal create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.cabal.out create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.out create mode 100644 cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.test.hs create mode 100644 changelog.d/pr-8534 diff --git a/Cabal/Cabal.cabal b/Cabal/Cabal.cabal index 4544ce8278f..b03d460ac24 100644 --- a/Cabal/Cabal.cabal +++ b/Cabal/Cabal.cabal @@ -89,6 +89,7 @@ library Distribution.Simple.Bench Distribution.Simple.Build Distribution.Simple.Build.Macros + Distribution.Simple.Build.PackageInfoModule Distribution.Simple.Build.PathsModule Distribution.Simple.BuildPaths Distribution.Simple.BuildTarget @@ -319,6 +320,7 @@ library Distribution.GetOpt Distribution.Lex Distribution.Simple.Build.Macros.Z + Distribution.Simple.Build.PackageInfoModule.Z Distribution.Simple.Build.PathsModule.Z Distribution.Simple.GHC.EnvironmentParser Distribution.Simple.GHC.Internal diff --git a/Cabal/src/Distribution/PackageDescription/Check.hs b/Cabal/src/Distribution/PackageDescription/Check.hs index 1908b6a412e..c4944bd0a96 100644 --- a/Cabal/src/Distribution/PackageDescription/Check.hs +++ b/Cabal/src/Distribution/PackageDescription/Check.hs @@ -50,7 +50,7 @@ import Distribution.PackageDescription import Distribution.PackageDescription.Configuration import Distribution.Parsec.Warning (PWarning, showPWarning) import Distribution.Pretty (prettyShow) -import Distribution.Simple.BuildPaths (autogenPathsModuleName) +import Distribution.Simple.BuildPaths (autogenPackageInfoModuleName, autogenPathsModuleName) import Distribution.Simple.BuildToolDepends import Distribution.Simple.CCompiler import Distribution.Simple.Glob @@ -220,6 +220,7 @@ data CheckExplanation = | CVCustomSetup | CVExpliticDepsCustomSetup | CVAutogenPaths + | CVAutogenPackageInfo | GlobNoMatch String String | GlobExactMatch String String FilePath | GlobNoDir String String FilePath @@ -231,7 +232,8 @@ data CheckExplanation = | SuspiciousFlagName [String] | DeclaredUsedFlags (Set FlagName) (Set FlagName) | NonASCIICustomField [String] - | RebindableClash + | RebindableClashPaths + | RebindableClashPackageInfo | WErrorUnneeded String | JUnneeded String | FDeferTypeErrorsUnneeded String @@ -648,6 +650,13 @@ ppExplanation CVAutogenPaths = ++ "the module does not come with the package and is generated on " ++ "setup. Modules built with a custom Setup.hs script also go here " ++ "to ensure that commands like sdist don't fail." +ppExplanation CVAutogenPackageInfo = + "Packages using 'cabal-version: 2.0' and the autogenerated " + ++ "module PackageInfo_* must include it in 'autogen-modules' as well as" + ++ " 'exposed-modules' and 'other-modules'. This specifies that " + ++ "the module does not come with the package and is generated on " + ++ "setup. Modules built with a custom Setup.hs script also go here " + ++ "to ensure that commands like sdist don't fail." ppExplanation (GlobNoMatch field glob) = "In '" ++ field ++ "': the pattern '" ++ glob ++ "' does not" ++ " match any files." @@ -700,12 +709,18 @@ ppExplanation (NonASCIICustomField nonAsciiXFields) = "Non ascii custom fields: " ++ unwords nonAsciiXFields ++ ". " ++ "For better compatibility, custom field names " ++ "shouldn't contain non-ascii characters." -ppExplanation RebindableClash = +ppExplanation RebindableClashPaths = "Packages using RebindableSyntax with OverloadedStrings or" ++ " OverloadedLists in default-extensions, in conjunction with the" ++ " autogenerated module Paths_*, are known to cause compile failures" ++ " with Cabal < 2.2. To use these default-extensions with a Paths_*" ++ " autogen module, specify at least 'cabal-version: 2.2'." +ppExplanation RebindableClashPackageInfo = + "Packages using RebindableSyntax with OverloadedStrings or" + ++ " OverloadedLists in default-extensions, in conjunction with the" + ++ " autogenerated module PackageInfo_*, are known to cause compile failures" + ++ " with Cabal < 2.2. To use these default-extensions with a PackageInfo_*" + ++ " autogen module, specify at least 'cabal-version: 2.2'." ppExplanation (WErrorUnneeded fieldName) = addConditionalExp $ "'" ++ fieldName ++ ": -Werror' makes the package easy to " ++ "break with future GHC versions because new GHC versions often " @@ -851,6 +866,7 @@ checkPackage gpkg mpkg = ++ checkUnusedFlags gpkg ++ checkUnicodeXFields gpkg ++ checkPathsModuleExtensions pkg + ++ checkPackageInfoModuleExtensions pkg ++ checkSetupVersions gpkg ++ checkDuplicateModules gpkg where @@ -1749,6 +1765,11 @@ checkCabalVersion pkg = && not (elem (autogenPathsModuleName pkg) allModuleNamesAutogen) ) $ PackageDistInexcusable CVAutogenPaths + , check (specVersion pkg >= CabalSpecV2_0 + && elem (autogenPackageInfoModuleName pkg) allModuleNames + && not (elem (autogenPackageInfoModuleName pkg) allModuleNamesAutogen) ) $ + PackageDistInexcusable CVAutogenPackageInfo + ] where -- Perform a check on packages that use a version of the spec less than @@ -1925,13 +1946,25 @@ checkUnicodeXFields gpd -- | cabal-version <2.2 + Paths_module + default-extensions: doesn't build. checkPathsModuleExtensions :: PackageDescription -> [PackageCheck] -checkPathsModuleExtensions pd +checkPathsModuleExtensions = checkAutogenModuleExtensions autogenPathsModuleName RebindableClashPaths + +-- | cabal-version <2.2 + PackageInfo_module + default-extensions: doesn't build. +checkPackageInfoModuleExtensions :: PackageDescription -> [PackageCheck] +checkPackageInfoModuleExtensions = checkAutogenModuleExtensions autogenPackageInfoModuleName RebindableClashPackageInfo + +-- | cabal-version <2.2 + *_module + default-extensions: doesn't build. +checkAutogenModuleExtensions :: + (PackageDescription -> ModuleName) -> + CheckExplanation -> + PackageDescription -> + [PackageCheck] +checkAutogenModuleExtensions autogenModuleName rebindableClashExplanation pd | specVersion pd >= CabalSpecV2_2 = [] | any checkBI (allBuildInfo pd) || any checkLib (allLibraries pd) - = return (PackageBuildImpossible RebindableClash) + = return (PackageBuildImpossible rebindableClashExplanation) | otherwise = [] where - mn = autogenPathsModuleName pd + mn = autogenModuleName pd checkLib :: Library -> Bool checkLib l = mn `elem` exposedModules l && checkExts (l ^. L.defaultExtensions) diff --git a/Cabal/src/Distribution/Simple/Build.hs b/Cabal/src/Distribution/Simple/Build.hs index ad1161155d3..b4f1c2d7f12 100644 --- a/Cabal/src/Distribution/Simple/Build.hs +++ b/Cabal/src/Distribution/Simple/Build.hs @@ -55,6 +55,7 @@ import qualified Distribution.Simple.HaskellSuite as HaskellSuite import qualified Distribution.Simple.PackageIndex as Index import Distribution.Simple.Build.Macros (generateCabalMacrosHeader) +import Distribution.Simple.Build.PackageInfoModule (generatePackageInfoModule) import Distribution.Simple.Build.PathsModule (generatePathsModule) import qualified Distribution.Simple.Program.HcPkg as HcPkg @@ -773,7 +774,7 @@ componentInitialBuildSteps _distPref pkg_descr lbi clbi verbosity = do writeAutogenFiles verbosity pkg_descr lbi clbi --- | Generate and write out the Paths_.hs and cabal_macros.h files +-- | Generate and write out the Paths_.hs, PackageInfo_.hs, and cabal_macros.h files -- writeAutogenFiles :: Verbosity -> PackageDescription @@ -790,6 +791,13 @@ writeAutogenFiles verbosity pkg lbi clbi = do createDirectoryIfMissingVerbose verbosity True pathsModuleDir rewriteFileEx verbosity pathsModulePath (generatePathsModule pkg lbi clbi) + let packageInfoModulePath = autogenComponentModulesDir lbi clbi + ModuleName.toFilePath (autogenPackageInfoModuleName pkg) <.> "hs" + packageInfoModuleDir = takeDirectory packageInfoModulePath + -- Ensure that the directory exists! + createDirectoryIfMissingVerbose verbosity True packageInfoModuleDir + rewriteFileEx verbosity packageInfoModulePath (generatePackageInfoModule pkg lbi) + --TODO: document what we're doing here, and move it to its own function case clbi of LibComponentLocalBuildInfo { componentInstantiatedWith = insts } -> diff --git a/Cabal/src/Distribution/Simple/Build/PackageInfoModule.hs b/Cabal/src/Distribution/Simple/Build/PackageInfoModule.hs new file mode 100644 index 00000000000..6b33c0c84c0 --- /dev/null +++ b/Cabal/src/Distribution/Simple/Build/PackageInfoModule.hs @@ -0,0 +1,56 @@ +----------------------------------------------------------------------------- +-- | +-- Module : Distribution.Simple.Build.PackageInfoModule +-- Copyright : +-- +-- Maintainer : cabal-devel@haskell.org +-- Portability : portable +-- +-- Generating the PackageInfo_pkgname module. +-- +-- This is a module that Cabal generates for the benefit of packages. It +-- enables them to find their package informations. +-- +module Distribution.Simple.Build.PackageInfoModule ( + generatePackageInfoModule + ) where + +import Distribution.Compat.Prelude +import Prelude () + +import Distribution.Package +import Distribution.PackageDescription +import Distribution.Simple.Compiler +import Distribution.Simple.LocalBuildInfo +import Distribution.Utils.ShortText +import Distribution.Version + +import qualified Distribution.Simple.Build.PackageInfoModule.Z as Z + +-- ------------------------------------------------------------ +-- * Building Paths_.hs +-- ------------------------------------------------------------ + +generatePackageInfoModule :: PackageDescription -> LocalBuildInfo -> String +generatePackageInfoModule pkg_descr lbi = Z.render Z.Z + { Z.zPackageName = showPkgName $ packageName pkg_descr + , Z.zVersionDigits = show $ versionNumbers $ packageVersion pkg_descr + , Z.zSynopsis = fromShortText $ synopsis pkg_descr + , Z.zCopyright = fromShortText $ copyright pkg_descr + , Z.zHomepage = fromShortText $ homepage pkg_descr + , Z.zSupportsNoRebindableSyntax = supports_rebindable_syntax + } + where + supports_rebindable_syntax = ghc_newer_than (mkVersion [7,0,1]) + + ghc_newer_than minVersion = + case compilerCompatVersion GHC (compiler lbi) of + Nothing -> False + Just version -> version `withinRange` orLaterVersion minVersion + +showPkgName :: PackageName -> String +showPkgName = map fixchar . unPackageName + +fixchar :: Char -> Char +fixchar '-' = '_' +fixchar c = c diff --git a/Cabal/src/Distribution/Simple/Build/PackageInfoModule/Z.hs b/Cabal/src/Distribution/Simple/Build/PackageInfoModule/Z.hs new file mode 100644 index 00000000000..e96ed923045 --- /dev/null +++ b/Cabal/src/Distribution/Simple/Build/PackageInfoModule/Z.hs @@ -0,0 +1,60 @@ +{-# LANGUAGE DeriveGeneric #-} + +module Distribution.Simple.Build.PackageInfoModule.Z (render, Z (..)) where + +import Distribution.ZinzaPrelude + +data Z = Z + { zPackageName :: String, + zVersionDigits :: String, + zSynopsis :: String, + zCopyright :: String, + zHomepage :: String, + zSupportsNoRebindableSyntax :: Bool + } + deriving (Generic) + +render :: Z -> String +render z_root = execWriter $ do + if (zSupportsNoRebindableSyntax z_root) + then do + tell "{-# LANGUAGE NoRebindableSyntax #-}\n" + return () + else do + return () + tell "{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}\n" + tell "{-# OPTIONS_GHC -w #-}\n" + tell "module PackageInfo_" + tell (zPackageName z_root) + tell " (\n" + tell " name,\n" + tell " version,\n" + tell " synopsis,\n" + tell " copyright,\n" + tell " homepage,\n" + tell " ) where\n" + tell "\n" + tell "import Data.Version (Version(..))\n" + tell "import Prelude\n" + tell "\n" + tell "name :: String\n" + tell "name = " + tell (show $ zPackageName z_root) + tell "\n" + tell "version :: Version\n" + tell "version = Version " + tell (zVersionDigits z_root) + tell " []\n" + tell "\n" + tell "synopsis :: String\n" + tell "synopsis = " + tell (show $ zSynopsis z_root) + tell "\n" + tell "copyright :: String\n" + tell "copyright = " + tell (show $ zCopyright z_root) + tell "\n" + tell "homepage :: String\n" + tell "homepage = " + tell (show $ zHomepage z_root) + tell "\n" diff --git a/Cabal/src/Distribution/Simple/BuildPaths.hs b/Cabal/src/Distribution/Simple/BuildPaths.hs index 078633874d1..189de54785f 100644 --- a/Cabal/src/Distribution/Simple/BuildPaths.hs +++ b/Cabal/src/Distribution/Simple/BuildPaths.hs @@ -20,6 +20,7 @@ module Distribution.Simple.BuildPaths ( autogenComponentModulesDir, autogenPathsModuleName, + autogenPackageInfoModuleName, cppHeaderName, haddockName, @@ -105,6 +106,14 @@ autogenPathsModuleName pkg_descr = where fixchar '-' = '_' fixchar c = c +-- | The name of the auto-generated PackageInfo_* module associated with a package +autogenPackageInfoModuleName :: PackageDescription -> ModuleName +autogenPackageInfoModuleName pkg_descr = + ModuleName.fromString $ + "PackageInfo_" ++ map fixchar (prettyShow (packageName pkg_descr)) + where fixchar '-' = '_' + fixchar c = c + haddockName :: PackageDescription -> FilePath haddockName pkg_descr = prettyShow (packageName pkg_descr) <.> "haddock" diff --git a/Cabal/src/Distribution/Simple/SrcDist.hs b/Cabal/src/Distribution/Simple/SrcDist.hs index 3bba81bed94..1cb2b841063 100644 --- a/Cabal/src/Distribution/Simple/SrcDist.hs +++ b/Cabal/src/Distribution/Simple/SrcDist.hs @@ -361,8 +361,10 @@ filterAutogenModules pkg_descr0 = mapLib filterAutogenModuleLib $ otherModules = filter (filterFunction bi) (otherModules bi) } pathsModule = autogenPathsModuleName pkg_descr0 + packageInfoModule = autogenPackageInfoModuleName pkg_descr0 filterFunction bi = \mn -> mn /= pathsModule + && mn /= packageInfoModule && not (mn `elem` autogenModules bi) -- | Prepare a directory tree of source files for a snapshot version. diff --git a/cabal-testsuite/PackageTests/AutogenModules/Package/my.cabal b/cabal-testsuite/PackageTests/AutogenModules/Package/my.cabal index 4119742ce24..37dfcbf7bce 100644 --- a/cabal-testsuite/PackageTests/AutogenModules/Package/my.cabal +++ b/cabal-testsuite/PackageTests/AutogenModules/Package/my.cabal @@ -17,6 +17,7 @@ Library build-depends: base exposed-modules: MyLibrary + PackageInfo_AutogenModules Paths_AutogenModules MyLibHelperModule other-modules: @@ -30,6 +31,7 @@ Executable Exe build-depends: base other-modules: MyExeModule + PackageInfo_AutogenModules Paths_AutogenModules MyExeHelperModule autogen-modules: @@ -42,6 +44,7 @@ Test-Suite Test build-depends: base other-modules: MyTestModule + PackageInfo_AutogenModules Paths_AutogenModules MyTestHelperModule autogen-modules: @@ -54,6 +57,7 @@ Benchmark Bench build-depends: base other-modules: MyBenchModule + PackageInfo_AutogenModules Paths_AutogenModules MyBenchHelperModule autogen-modules: diff --git a/cabal-testsuite/PackageTests/AutogenModules/Package/setup.cabal.out b/cabal-testsuite/PackageTests/AutogenModules/Package/setup.cabal.out index 77bb223e542..a650205c593 100644 --- a/cabal-testsuite/PackageTests/AutogenModules/Package/setup.cabal.out +++ b/cabal-testsuite/PackageTests/AutogenModules/Package/setup.cabal.out @@ -14,6 +14,7 @@ On executable 'Exe' an 'autogen-module' is not on 'other-modules' On test suite 'Test' an 'autogen-module' is not on 'other-modules' On benchmark 'Bench' an 'autogen-module' is not on 'other-modules' Packages using 'cabal-version: 2.0' and the autogenerated module Paths_* must include it also on the 'autogen-modules' field besides 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail. +Packages using 'cabal-version: 2.0' and the autogenerated module PackageInfo_* must include it in 'autogen-modules' as well as 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail. The filename './my.cabal' does not match package name (expected: 'AutogenModules.cabal') Note: the public hackage server would reject this package. Building source dist for AutogenModules-0.1... diff --git a/cabal-testsuite/PackageTests/AutogenModules/Package/setup.out b/cabal-testsuite/PackageTests/AutogenModules/Package/setup.out index d6a70b80359..c6203a64130 100644 --- a/cabal-testsuite/PackageTests/AutogenModules/Package/setup.out +++ b/cabal-testsuite/PackageTests/AutogenModules/Package/setup.out @@ -14,6 +14,7 @@ On executable 'Exe' an 'autogen-module' is not on 'other-modules' On test suite 'Test' an 'autogen-module' is not on 'other-modules' On benchmark 'Bench' an 'autogen-module' is not on 'other-modules' Packages using 'cabal-version: 2.0' and the autogenerated module Paths_* must include it also on the 'autogen-modules' field besides 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail. +Packages using 'cabal-version: 2.0' and the autogenerated module PackageInfo_* must include it in 'autogen-modules' as well as 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail. The filename './my.cabal' does not match package name (expected: 'AutogenModules.cabal') Note: the public hackage server would reject this package. Building source dist for AutogenModules-0.1... diff --git a/cabal-testsuite/PackageTests/AutogenModules/SrcDist/AutogenModules.cabal b/cabal-testsuite/PackageTests/AutogenModules/SrcDist/AutogenModules.cabal index 92479b0c948..8c8f1a98b89 100644 --- a/cabal-testsuite/PackageTests/AutogenModules/SrcDist/AutogenModules.cabal +++ b/cabal-testsuite/PackageTests/AutogenModules/SrcDist/AutogenModules.cabal @@ -17,11 +17,13 @@ Library build-depends: base exposed-modules: MyLibrary + PackageInfo_AutogenModules Paths_AutogenModules MyLibHelperModule other-modules: MyLibModule autogen-modules: + PackageInfo_AutogenModules Paths_AutogenModules MyLibHelperModule @@ -31,9 +33,11 @@ Executable Exe build-depends: base other-modules: MyExeModule + PackageInfo_AutogenModules Paths_AutogenModules MyExeHelperModule autogen-modules: + PackageInfo_AutogenModules Paths_AutogenModules MyExeHelperModule @@ -44,9 +48,11 @@ Test-Suite Test build-depends: base other-modules: MyTestModule + PackageInfo_AutogenModules Paths_AutogenModules MyTestHelperModule autogen-modules: + PackageInfo_AutogenModules Paths_AutogenModules MyTestHelperModule @@ -57,8 +63,10 @@ Benchmark Bench build-depends: base other-modules: MyBenchModule + PackageInfo_AutogenModules Paths_AutogenModules MyBenchHelperModule autogen-modules: + PackageInfo_AutogenModules Paths_AutogenModules MyBenchHelperModule diff --git a/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.test.hs b/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.test.hs index b6be6672ccb..84d702c57d2 100644 --- a/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.test.hs +++ b/cabal-testsuite/PackageTests/AutogenModules/SrcDist/setup.test.hs @@ -25,16 +25,16 @@ main = setupAndCabalTest $ do let gotTestSuite = head $ testSuites (localPkgDescr lbi) let gotBenchmark = head $ benchmarks (localPkgDescr lbi) assertEqual "library 'autogen-modules' field does not match expected" - [fromString "Paths_AutogenModules", fromString "MyLibHelperModule"] + [fromString "PackageInfo_AutogenModules", fromString "Paths_AutogenModules", fromString "MyLibHelperModule"] (libModulesAutogen gotLibrary) assertEqual "executable 'autogen-modules' field does not match expected" - [fromString "Paths_AutogenModules", fromString "MyExeHelperModule"] + [fromString "PackageInfo_AutogenModules", fromString "Paths_AutogenModules", fromString "MyExeHelperModule"] (exeModulesAutogen gotExecutable) assertEqual "test-suite 'autogen-modules' field does not match expected" - [fromString "Paths_AutogenModules", fromString "MyTestHelperModule"] + [fromString "PackageInfo_AutogenModules", fromString "Paths_AutogenModules", fromString "MyTestHelperModule"] (testModulesAutogen gotTestSuite) assertEqual "benchmark 'autogen-modules' field does not match expected" - [fromString "Paths_AutogenModules", fromString "MyBenchHelperModule"] + [fromString "PackageInfo_AutogenModules", fromString "Paths_AutogenModules", fromString "MyBenchHelperModule"] (benchmarkModulesAutogen gotBenchmark) -- Package check messages. diff --git a/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/cabal.out b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/cabal.out index 75379f0b1d2..6ed067c93ac 100644 --- a/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/cabal.out +++ b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/cabal.out @@ -1,4 +1,5 @@ # cabal check Warning: The following errors will cause portability problems on other environments: Warning: Packages using 'cabal-version: 2.0' and the autogenerated module Paths_* must include it also on the 'autogen-modules' field besides 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail. +Warning: Packages using 'cabal-version: 2.0' and the autogenerated module PackageInfo_* must include it in 'autogen-modules' as well as 'exposed-modules' and 'other-modules'. This specifies that the module does not come with the package and is generated on setup. Modules built with a custom Setup.hs script also go here to ensure that commands like sdist don't fail. Warning: Hackage would reject this package. diff --git a/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/pkg.cabal b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/pkg.cabal index a00327cd1b5..8486891a3e3 100644 --- a/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/pkg.cabal +++ b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/CabalVersion/AutoGenMods/pkg.cabal @@ -11,5 +11,7 @@ license-file: LICENSE library exposed-modules: Module - other-modules: Paths_pkg + other-modules: + PackageInfo_pkg + Paths_pkg default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/cabal.out b/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/cabal.out index 2efd21d37f1..d21149b6c45 100644 --- a/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/cabal.out +++ b/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/cabal.out @@ -1,4 +1,5 @@ # cabal check Warning: The package will not build sanely due to these errors: Warning: Packages using RebindableSyntax with OverloadedStrings or OverloadedLists in default-extensions, in conjunction with the autogenerated module Paths_*, are known to cause compile failures with Cabal < 2.2. To use these default-extensions with a Paths_* autogen module, specify at least 'cabal-version: 2.2'. +Warning: Packages using RebindableSyntax with OverloadedStrings or OverloadedLists in default-extensions, in conjunction with the autogenerated module PackageInfo_*, are known to cause compile failures with Cabal < 2.2. To use these default-extensions with a PackageInfo_* autogen module, specify at least 'cabal-version: 2.2'. Warning: Hackage would reject this package. diff --git a/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/pkg.cabal b/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/pkg.cabal index a3f160d87d9..940f48a3cbb 100644 --- a/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/pkg.cabal +++ b/cabal-testsuite/PackageTests/Check/NonConfCheck/PathsExtensions/pkg.cabal @@ -11,8 +11,12 @@ license-file: LICENSE library exposed-modules: Foo - autogen-modules: Paths_pkg - other-modules: Paths_pkg + autogen-modules: + PackageInfo_pkg + Paths_pkg + other-modules: + PackageInfo_pkg + Paths_pkg default-language: Haskell2010 default-extensions: RebindableSyntax, OverloadedLists diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdRun/Datafiles/foo/foo.cabal b/cabal-testsuite/PackageTests/NewBuild/CmdRun/Datafiles/foo/foo.cabal index ebd41dbf39b..b69379dd383 100644 --- a/cabal-testsuite/PackageTests/NewBuild/CmdRun/Datafiles/foo/foo.cabal +++ b/cabal-testsuite/PackageTests/NewBuild/CmdRun/Datafiles/foo/foo.cabal @@ -12,7 +12,9 @@ executable foo library exposed-modules: LibFoo - other-modules: Paths_foo + other-modules: + PackageInfo_foo + Paths_foo build-depends: base default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/setup-lib.cabal b/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/setup-lib.cabal index 7ec9ecb06b2..8f0faefa08c 100644 --- a/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/setup-lib.cabal +++ b/cabal-testsuite/PackageTests/NewBuild/T5164/setup-lib/setup-lib.cabal @@ -6,6 +6,8 @@ data-files: example.txt library exposed-modules: SetupLib - other-modules: Paths_setup_lib + other-modules: + PackageInfo_setup_lib + Paths_setup_lib build-depends: base default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/Executable/Main.hs b/cabal-testsuite/PackageTests/PackageInfoModule/Executable/Main.hs new file mode 100644 index 00000000000..f3938673575 --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/Executable/Main.hs @@ -0,0 +1,7 @@ +module Main where + +import PackageInfo_PackageInfoModule (version) + +main :: IO () +main = do + print version diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/Executable/my.cabal b/cabal-testsuite/PackageTests/PackageInfoModule/Executable/my.cabal new file mode 100644 index 00000000000..f04d2696c6c --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/Executable/my.cabal @@ -0,0 +1,18 @@ +name: PackageInfoModule +version: 0.1 +license: BSD3 +author: Gautier DI FOLCO +stability: stable +category: PackageTests +build-type: Simple +Cabal-version: >= 1.2 + +description: + Check that the generated package info module compiles. + +Executable TestPackageInfoModule + main-is: Main.hs + other-modules: + PackageInfo_PackageInfoModule + Paths_PackageInfoModule + build-depends: base diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.cabal.out b/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.cabal.out new file mode 100644 index 00000000000..6a480f6f576 --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.cabal.out @@ -0,0 +1,5 @@ +# Setup configure +Configuring PackageInfoModule-0.1... +# Setup build +Preprocessing executable 'TestPackageInfoModule' for PackageInfoModule-0.1.. +Building executable 'TestPackageInfoModule' for PackageInfoModule-0.1.. diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.out b/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.out new file mode 100644 index 00000000000..6a480f6f576 --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.out @@ -0,0 +1,5 @@ +# Setup configure +Configuring PackageInfoModule-0.1... +# Setup build +Preprocessing executable 'TestPackageInfoModule' for PackageInfoModule-0.1.. +Building executable 'TestPackageInfoModule' for PackageInfoModule-0.1.. diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.test.hs b/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.test.hs new file mode 100644 index 00000000000..ac477fa7567 --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/Executable/setup.test.hs @@ -0,0 +1,4 @@ +import Test.Cabal.Prelude +-- Test that Paths module is generated and available for executables. +main = setupAndCabalTest $ setup_build [] + diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/Main.hs b/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/Main.hs new file mode 100644 index 00000000000..d82a4bd93b7 --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/Main.hs @@ -0,0 +1,4 @@ +module Main where + +main :: IO () +main = return () diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/my.cabal b/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/my.cabal new file mode 100644 index 00000000000..7704aaa15b8 --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/my.cabal @@ -0,0 +1,19 @@ +name: PackageInfoModule +version: 0.1 +license: BSD3 +author: Gautier DI FOLCO +category: PackageTests +build-type: Simple +Cabal-version: >= 1.2 + +description: + Check that the generated package info module compiles. + +Executable TestPackageInfoModule + main-is: Main.hs + if impl(ghc >= 8.10.0) + ghc-options: -Werror -fwarn-prepositive-qualified-module + other-modules: + PackageInfo_PackageInfoModule + Paths_PackageInfoModule + build-depends: base diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.cabal.out b/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.cabal.out new file mode 100644 index 00000000000..6a480f6f576 --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.cabal.out @@ -0,0 +1,5 @@ +# Setup configure +Configuring PackageInfoModule-0.1... +# Setup build +Preprocessing executable 'TestPackageInfoModule' for PackageInfoModule-0.1.. +Building executable 'TestPackageInfoModule' for PackageInfoModule-0.1.. diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.out b/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.out new file mode 100644 index 00000000000..6a480f6f576 --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.out @@ -0,0 +1,5 @@ +# Setup configure +Configuring PackageInfoModule-0.1... +# Setup build +Preprocessing executable 'TestPackageInfoModule' for PackageInfoModule-0.1.. +Building executable 'TestPackageInfoModule' for PackageInfoModule-0.1.. diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.test.hs b/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.test.hs new file mode 100644 index 00000000000..ac477fa7567 --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/ImportQualifiedPost/setup.test.hs @@ -0,0 +1,4 @@ +import Test.Cabal.Prelude +-- Test that Paths module is generated and available for executables. +main = setupAndCabalTest $ setup_build [] + diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/Library/my.cabal b/cabal-testsuite/PackageTests/PackageInfoModule/Library/my.cabal new file mode 100644 index 00000000000..b356e8929ea --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/Library/my.cabal @@ -0,0 +1,36 @@ +Cabal-version: 2.2 +name: PackageInfoModule +version: 0.1 +license: BSD-3-Clause +author: Gautier DI FOLCO +stability: stable +category: PackageTests +build-type: Simple + +description: + Check that the generated package info module compiles. + +Library + exposed-modules: + PackageInfo_PackageInfoModule + Paths_PackageInfoModule + build-depends: base + default-language: Haskell2010 + default-extensions: + -- This is a non-exhaustive list of extensions that can cause code to + -- not compile when it would if the extension was disabled. This ensures + -- that autogen modules are compatible with default extensions. + NoImplicitPrelude + CPP + TemplateHaskell + QuasiQuotes + Arrows + OverloadedStrings + if impl(ghc >= 6.12) + default-extensions: MonoLocalBinds + if impl(ghc >= 7.0.1) + default-extensions: RebindableSyntax + if impl(ghc >= 7.4.1) + default-extensions: NoTraditionalRecordSyntax + if impl(ghc >= 7.8.1) + default-extensions: OverloadedLists diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.cabal.out b/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.cabal.out new file mode 100644 index 00000000000..65d22a5fc4a --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.cabal.out @@ -0,0 +1,5 @@ +# Setup configure +Configuring PackageInfoModule-0.1... +# Setup build +Preprocessing library for PackageInfoModule-0.1.. +Building library for PackageInfoModule-0.1.. diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.out b/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.out new file mode 100644 index 00000000000..65d22a5fc4a --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.out @@ -0,0 +1,5 @@ +# Setup configure +Configuring PackageInfoModule-0.1... +# Setup build +Preprocessing library for PackageInfoModule-0.1.. +Building library for PackageInfoModule-0.1.. diff --git a/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.test.hs b/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.test.hs new file mode 100644 index 00000000000..7c55afb42ca --- /dev/null +++ b/cabal-testsuite/PackageTests/PackageInfoModule/Library/setup.test.hs @@ -0,0 +1,3 @@ +import Test.Cabal.Prelude +-- Test that Paths module is generated and available for libraries. +main = setupAndCabalTest $ setup_build [] diff --git a/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/my.cabal b/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/my.cabal index 29a319ad43f..04337c3f3f7 100644 --- a/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/my.cabal +++ b/cabal-testsuite/PackageTests/PathsModule/Executable-Relocatable/my.cabal @@ -12,5 +12,7 @@ description: Executable TestPathsModule main-is: Main.hs - other-modules: Paths_PathsModule + other-modules: + PackageInfo_PathsModule + Paths_PathsModule build-depends: base diff --git a/cabal-testsuite/PackageTests/PathsModule/Executable/my.cabal b/cabal-testsuite/PackageTests/PathsModule/Executable/my.cabal index 29a319ad43f..04337c3f3f7 100644 --- a/cabal-testsuite/PackageTests/PathsModule/Executable/my.cabal +++ b/cabal-testsuite/PackageTests/PathsModule/Executable/my.cabal @@ -12,5 +12,7 @@ description: Executable TestPathsModule main-is: Main.hs - other-modules: Paths_PathsModule + other-modules: + PackageInfo_PathsModule + Paths_PathsModule build-depends: base diff --git a/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/my.cabal b/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/my.cabal index 8ad771ececd..faacd4f1ff0 100644 --- a/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/my.cabal +++ b/cabal-testsuite/PackageTests/PathsModule/ImportQualifiedPost/my.cabal @@ -13,5 +13,7 @@ Executable TestPathsModule main-is: Main.hs if impl(ghc >= 8.10.0) ghc-options: -Werror -fwarn-prepositive-qualified-module - other-modules: Paths_PathsModule + other-modules: + PackageInfo_PathsModule + Paths_PathsModule build-depends: base diff --git a/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal b/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal index 5260d9cbd5c..47ee1f942d1 100644 --- a/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal +++ b/cabal-testsuite/PackageTests/PathsModule/Library/my.cabal @@ -11,7 +11,9 @@ description: Check that the generated paths module compiles. Library - exposed-modules: Paths_PathsModule + exposed-modules: + PackageInfo_PathsModule + Paths_PathsModule build-depends: base default-language: Haskell2010 default-extensions: diff --git a/cabal-testsuite/PackageTests/PathsModule/MissingSafeHaskellMode/my.cabal b/cabal-testsuite/PackageTests/PathsModule/MissingSafeHaskellMode/my.cabal index 355f5819120..44140ee9019 100644 --- a/cabal-testsuite/PackageTests/PathsModule/MissingSafeHaskellMode/my.cabal +++ b/cabal-testsuite/PackageTests/PathsModule/MissingSafeHaskellMode/my.cabal @@ -11,7 +11,9 @@ description: Check that the generated paths module compiles. Library - exposed-modules: Paths_PathsModule + exposed-modules: + PackageInfo_PathsModule + Paths_PathsModule build-depends: base default-language: Haskell2010 diff --git a/changelog.d/pr-8534 b/changelog.d/pr-8534 new file mode 100644 index 00000000000..2e654063ca6 --- /dev/null +++ b/changelog.d/pr-8534 @@ -0,0 +1,10 @@ +synopsis: Add PackageInfo_ module +packages: Cabal +prs: #8534 +significance: significant + +description: { + +- Add PackageInfo_ module to embed portable package-related informations (issue #3909) + +} diff --git a/doc/cabal-package.rst b/doc/cabal-package.rst index 8ad0a1ac06c..a5af5ad3416 100644 --- a/doc/cabal-package.rst +++ b/doc/cabal-package.rst @@ -3157,12 +3157,29 @@ the configured data directory for ``pretty-show`` is controlled with the Accessing the package version ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The aforementioned auto generated :file:`Paths_{pkgname}` module also -exports the constant ``version ::`` -`Version `__ +The auto generated :file:`PackageInfo_{pkgname}` module exports the constant +``version ::`` `Version `__ which is defined as the version of your package as specified in the ``version`` field. +Accessing package-related informations +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The auto generated :file:`PackageInfo_{pkgname}` module exports the following +package-related constants: + +.. code-block:: haskell + + name :: String + version :: Version + synopsis :: String + copyright :: String + homepage :: String + +Unlike :file:`Paths_{pkgname}` (see <#accessing-data-files-from-package-code>), +:file:`PackageInfo_{pkgname}` is system- and path-independent. It aims to be +easier to work with for hash-based tools such as Nix. + .. _system-dependent parameters: System-dependent parameters