From bacf8a16d607341b11f06d1b581e5738b58f8181 Mon Sep 17 00:00:00 2001 From: Finley McIlwaine Date: Tue, 15 Aug 2023 16:21:15 -0600 Subject: [PATCH] Do not use tmp dirs for Haddock, add --no-haddock-version-cpp, and more Haddock no longer writes compilation files by default, so we do not need to pass tmp dirs for `-hidir`, `-stubdir`, and `-odir` via `--optghc`. Indeed, we do not *want* to do so, since it results in recompilation for every invocation of Haddock via Cabal. This commit stops this from happening. This commit also introduces the `--no-haddock-version-cpp` flag and `no-haddock-version-cpp:` cabal.project field, which prevent the definition of the `__HADDOCK_VERSION__` macro when invoking GHC through Haddock. This is essentially required in order for Haddock to be able to use existing compilation results and avoid recompilation, since the macro definition will trigger recompilation. This commit also renames the `--haddock-lib` flag to `--haddock-resources-dir` (and `haddock-lib:` cabal.project field to `haddock-resources-dir:`), and adds this flag to the users guide since it was missing an entry. This also allows us to add this field to `cabal-install:test:integration-tests2`, since it is no longer ambiguous with the `--lib` flag. This commit also causes `documentation: true` or `--enable-documentation` to imply `-haddock` for GHC. Also, since Haddock >= 2.29 is renaming `--lib` to `--resources-dir`, this commit switches the flag provided to Haddock using a backwards compatible condition based on the Haddock version. Adds a changelog entry. --- .gitignore | 3 + Cabal/src/Distribution/Simple/Haddock.hs | 144 +++++++++++------- .../src/Distribution/Simple/Setup/Haddock.hs | 38 +++-- .../Distribution/Client/CmdHaddockProject.hs | 3 +- .../src/Distribution/Client/Config.hs | 3 +- .../src/Distribution/Client/PackageHash.hs | 6 +- .../Client/ProjectConfig/Legacy.hs | 9 +- .../Client/ProjectConfig/Types.hs | 3 +- .../Distribution/Client/ProjectPlanning.hs | 18 ++- .../Client/ProjectPlanning/Types.hs | 3 +- .../src/Distribution/Client/Setup.hs | 3 +- cabal-install/tests/IntegrationTests2.hs | 2 + .../IntegrationTests2/config/default-config | 19 ++- .../Distribution/Client/ProjectConfig.hs | 9 +- .../PackageTests/NewHaddock/Fails/cabal.out | 3 +- changelog.d/pr-9177 | 26 ++++ doc/cabal-project.rst | 19 +++ test/IntegrationTests2/config/default-config | 7 +- .../nix-config/default-config | 7 +- tests/IntegrationTests2/config/default-config | 21 +-- .../nix-config/default-config | 7 +- 21 files changed, 248 insertions(+), 105 deletions(-) create mode 100644 changelog.d/pr-9177 diff --git a/.gitignore b/.gitignore index e9ec3b6322f..8430592bf6f 100644 --- a/.gitignore +++ b/.gitignore @@ -83,3 +83,6 @@ bench.html # Emacs .projectile + +# direnv +.envrc diff --git a/Cabal/src/Distribution/Simple/Haddock.hs b/Cabal/src/Distribution/Simple/Haddock.hs index a8394c21a6c..223a5ed8afb 100644 --- a/Cabal/src/Distribution/Simple/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Haddock.hs @@ -137,7 +137,7 @@ data HaddockArgs = HaddockArgs -- ^ Re-exported modules , argTargets :: [FilePath] -- ^ Modules to process. - , argLib :: Flag String + , argResourcesDir :: Flag String -- ^ haddock's static \/ auxiliary files. } deriving (Generic) @@ -287,6 +287,16 @@ haddock pkg_descr lbi suffixes flags' = do [] -> allTargetsInBuildOrder' pkg_descr lbi _ -> targets + version' = + if flag haddockNoVersionCPP + then Nothing + else Just version + + mtmp :: FilePath -> Maybe FilePath + mtmp + | version >= mkVersion [2, 28, 0] = const Nothing + | otherwise = Just + internalPackageDB <- createInternalPackageDB verbosity lbi (flag haddockDistPref) @@ -305,18 +315,18 @@ haddock pkg_descr lbi suffixes flags' = do preprocessComponent pkg_descr component lbi' clbi False verbosity suffixes let - doExe com = case (compToExe com) of + doExe com = case compToExe com of Just exe -> do withTempDirectoryEx verbosity tmpFileOpts (buildDir lbi') "tmp" $ \tmp -> do exeArgs <- fromExecutable verbosity - tmp + (mtmp tmp) lbi' clbi htmlTemplate - version + version' exe let exeArgs' = commonArgs `mappend` exeArgs runHaddock @@ -345,17 +355,17 @@ haddock pkg_descr lbi suffixes flags' = do (maybeComponentInstantiatedWith clbi) case component of CLib lib -> do - withTempDirectoryEx verbosity tmpFileOpts (buildDir lbi) "tmp" $ + withTempDirectoryEx verbosity tmpFileOpts (buildDir lbi') "tmp" $ \tmp -> do smsg libArgs <- fromLibrary verbosity - tmp + (mtmp tmp) lbi' clbi htmlTemplate - version + version' lib let libArgs' = commonArgs `mappend` libArgs runHaddock verbosity tmpFileOpts comp platform haddockProg True libArgs' @@ -392,20 +402,20 @@ haddock pkg_descr lbi suffixes flags' = do when (flag haddockForeignLibs) ( do - withTempDirectoryEx verbosity tmpFileOpts (buildDir lbi') "tmp" $ - \tmp -> do - smsg - flibArgs <- + smsg + flibArgs <- + withTempDirectoryEx verbosity tmpFileOpts (buildDir lbi') "tmp" $ + \tmp -> fromForeignLib verbosity - tmp + (mtmp tmp) lbi' clbi htmlTemplate - version + version' flib - let libArgs' = commonArgs `mappend` flibArgs - runHaddock verbosity tmpFileOpts comp platform haddockProg True libArgs' + let libArgs' = commonArgs `mappend` flibArgs + runHaddock verbosity tmpFileOpts comp platform haddockProg True libArgs' ) >> return index CExe _ -> when (flag haddockExecutables) (smsg >> doExe component) >> return index @@ -465,7 +475,7 @@ fromFlags env flags = (haddockIndex flags) , argGenIndex = Flag False , argBaseUrl = haddockBaseUrl flags - , argLib = haddockLib flags + , argResourcesDir = haddockResourcesDir flags , argVerbose = maybe mempty (Any . (>= deafening)) . flagToMaybe @@ -491,7 +501,7 @@ fromHaddockProjectFlags flags = , argPrologueFile = haddockProjectPrologue flags , argInterfaces = fromFlagOrDefault [] (haddockProjectInterfaces flags) , argLinkedSource = Flag True - , argLib = haddockProjectLib flags + , argResourcesDir = haddockProjectResourcesDir flags } fromPackageDescription :: HaddockTarget -> PackageDescription -> HaddockArgs @@ -536,26 +546,34 @@ componentGhcOptions verbosity lbi bi clbi odir = mkHaddockArgs :: Verbosity - -> FilePath + -> Maybe FilePath + -- ^ 'Nothing' to prevent passing temporary directories for -hidir, -odir, and + -- -stubdir to GHC through Haddock -> LocalBuildInfo -> ComponentLocalBuildInfo -> Maybe PathTemplate -- ^ template for HTML location - -> Version + -> Maybe Version + -- ^ 'Nothing' if the user requested not to define the __HADDOCK_VERSION__ + -- macro -> [FilePath] -> BuildInfo -> IO HaddockArgs -mkHaddockArgs verbosity tmp lbi clbi htmlTemplate haddockVersion inFiles bi = do +mkHaddockArgs verbosity mtmp lbi clbi htmlTemplate haddockVersion inFiles bi = do ifaceArgs <- getInterfaces verbosity lbi clbi htmlTemplate - let vanillaOpts = - (componentGhcOptions normal lbi bi clbi (buildDir lbi)) - { -- Noooooooooo!!!!!111 - -- haddock stomps on our precious .hi - -- and .o files. Workaround by telling - -- haddock to write them elsewhere. - ghcOptObjDir = toFlag tmp - , ghcOptHiDir = toFlag tmp - , ghcOptStubDir = toFlag tmp + let vanillaOpts' = + componentGhcOptions normal lbi bi clbi (buildDir lbi) + `mappend` getGhcCppOpts haddockVersion bi + vanillaOpts = + vanillaOpts' + { -- Starting with Haddock 2.28, we no longer want to run Haddock's + -- GHC session in a temporary directory. Doing so always causes + -- recompilation during documentation generation, which can now be + -- avoided thanks to Hi Haddock. See + -- https://github.com/haskell/cabal/pull/9177 for discussion. + ghcOptObjDir = maybe (ghcOptObjDir vanillaOpts') toFlag mtmp + , ghcOptHiDir = maybe (ghcOptHiDir vanillaOpts') toFlag mtmp + , ghcOptStubDir = maybe (ghcOptStubDir vanillaOpts') toFlag mtmp } `mappend` getGhcCppOpts haddockVersion bi sharedOpts = @@ -583,20 +601,24 @@ mkHaddockArgs verbosity tmp lbi clbi htmlTemplate haddockVersion inFiles bi = do fromLibrary :: Verbosity - -> FilePath + -> Maybe FilePath + -- ^ 'Nothing' to prevent passing temporary directories for -hidir, -odir, and + -- -stubdir to GHC through Haddock -> LocalBuildInfo -> ComponentLocalBuildInfo -> Maybe PathTemplate -- ^ template for HTML location - -> Version + -> Maybe Version + -- ^ 'Nothing' if the user requested not to define the __HADDOCK_VERSION__ + -- macro -> Library -> IO HaddockArgs -fromLibrary verbosity tmp lbi clbi htmlTemplate haddockVersion lib = do +fromLibrary verbosity mtmp lbi clbi htmlTemplate haddockVersion lib = do inFiles <- map snd `fmap` getLibSourceFiles verbosity lbi lib clbi args <- mkHaddockArgs verbosity - tmp + mtmp lbi clbi htmlTemplate @@ -610,20 +632,24 @@ fromLibrary verbosity tmp lbi clbi htmlTemplate haddockVersion lib = do fromExecutable :: Verbosity - -> FilePath + -> Maybe FilePath + -- ^ 'Nothing' to prevent passing temporary directories for -hidir, -odir, and + -- -stubdir to GHC through Haddock -> LocalBuildInfo -> ComponentLocalBuildInfo -> Maybe PathTemplate -- ^ template for HTML location - -> Version + -> Maybe Version + -- ^ 'Nothing' if the user requested not to define the __HADDOCK_VERSION__ + -- macro -> Executable -> IO HaddockArgs -fromExecutable verbosity tmp lbi clbi htmlTemplate haddockVersion exe = do +fromExecutable verbosity mtmp lbi clbi htmlTemplate haddockVersion exe = do inFiles <- map snd `fmap` getExeSourceFiles verbosity lbi exe clbi args <- mkHaddockArgs verbosity - tmp + mtmp lbi clbi htmlTemplate @@ -638,20 +664,24 @@ fromExecutable verbosity tmp lbi clbi htmlTemplate haddockVersion exe = do fromForeignLib :: Verbosity - -> FilePath + -> Maybe FilePath + -- ^ 'Nothing' to prevent passing temporary directories for -hidir, -odir, and + -- -stubdir to GHC through Haddock -> LocalBuildInfo -> ComponentLocalBuildInfo -> Maybe PathTemplate -- ^ template for HTML location - -> Version + -> Maybe Version + -- ^ 'Nothing' if the user requested not to define the __HADDOCK_VERSION__ + -- macro -> ForeignLib -> IO HaddockArgs -fromForeignLib verbosity tmp lbi clbi htmlTemplate haddockVersion flib = do +fromForeignLib verbosity mtmp lbi clbi htmlTemplate haddockVersion flib = do inFiles <- map snd `fmap` getFLibSourceFiles verbosity lbi flib clbi args <- mkHaddockArgs verbosity - tmp + mtmp lbi clbi htmlTemplate @@ -707,7 +737,9 @@ getReexports LibComponentLocalBuildInfo{componentExposedModules = mods} = getReexports _ = [] getGhcCppOpts - :: Version + :: Maybe Version + -- ^ 'Nothing' if the user requested not to define the __HADDOCK_VERSION__ + -- macro -> BuildInfo -> GhcOptions getGhcCppOpts haddockVersion bi = @@ -717,16 +749,21 @@ getGhcCppOpts haddockVersion bi = } where needsCpp = EnableExtension CPP `elem` usedExtensions bi - defines = [haddockVersionMacro] - haddockVersionMacro = - "-D__HADDOCK_VERSION__=" - ++ show (v1 * 1000 + v2 * 10 + v3) + defines = + [ "-D__HADDOCK_VERSION__=" ++ show vn + | Just vn <- [versionInt . versionNumbers <$> haddockVersion] + ] where - (v1, v2, v3) = case versionNumbers haddockVersion of - [] -> (0, 0, 0) - [x] -> (x, 0, 0) - [x, y] -> (x, y, 0) - (x : y : z : _) -> (x, y, z) + -- For some list xs = [x, y, z ...], versionInt xs results in + -- x * 1000 + y * 10 + z. E.g.: + -- >>> versionInt [2, 29, 0] + -- 2290 + -- >>> versionInt [3, 4] + -- 3040 + -- >>> versionInt [] + -- 0 + versionInt :: [Int] -> Int + versionInt = foldr ((+) . uncurry (*)) 0 . zip [1000, 10, 1] getGhcLibDir :: Verbosity @@ -922,7 +959,7 @@ renderPureArgs version comp platform args = , isVersion 2 19 ] , argTargets $ args - , maybe [] ((: []) . ("--lib=" ++)) . flagToMaybe . argLib $ args + , maybe [] ((: []) . (resourcesDirFlag ++)) . flagToMaybe . argResourcesDir $ args ] where renderInterfaces = map renderInterface @@ -964,6 +1001,9 @@ renderPureArgs version comp platform args = verbosityFlag | isVersion 2 5 = "--verbosity=1" | otherwise = "--verbose" + resourcesDirFlag + | isVersion 2 29 = "--resources-dir=" + | otherwise = "--lib=" haddockSupportsVisibility = version >= mkVersion [2, 26, 1] haddockSupportsPackageName = version > mkVersion [2, 16] diff --git a/Cabal/src/Distribution/Simple/Setup/Haddock.hs b/Cabal/src/Distribution/Simple/Setup/Haddock.hs index 3efc6640bd2..5f814ac3d35 100644 --- a/Cabal/src/Distribution/Simple/Setup/Haddock.hs +++ b/Cabal/src/Distribution/Simple/Setup/Haddock.hs @@ -103,9 +103,10 @@ data HaddockFlags = HaddockFlags , haddockVerbosity :: Flag Verbosity , haddockCabalFilePath :: Flag FilePath , haddockBaseUrl :: Flag String - , haddockLib :: Flag String + , haddockResourcesDir :: Flag String , haddockOutputDir :: Flag FilePath , haddockArgs :: [String] + , haddockNoVersionCPP :: Flag Bool } deriving (Show, Generic, Typeable) @@ -134,9 +135,10 @@ defaultHaddockFlags = , haddockCabalFilePath = mempty , haddockIndex = NoFlag , haddockBaseUrl = NoFlag - , haddockLib = NoFlag + , haddockResourcesDir = NoFlag , haddockOutputDir = NoFlag , haddockArgs = mempty + , haddockNoVersionCPP = Flag False } haddockCommand :: CommandUI HaddockFlags @@ -336,10 +338,10 @@ haddockOptions showOrParseArgs = (reqArgFlag "URL") , option "" - ["lib"] + ["resources-dir"] "location of Haddocks static / auxiliary files" - haddockLib - (\v flags -> flags{haddockLib = v}) + haddockResourcesDir + (\v flags -> flags{haddockResourcesDir = v}) (reqArgFlag "DIR") , option "" @@ -348,6 +350,13 @@ haddockOptions showOrParseArgs = haddockOutputDir (\v flags -> flags{haddockOutputDir = v}) (reqArgFlag "DIR") + , option + "" + ["no-version-cpp"] + "Do not define the __HADDOCK_VERSION__ macro when invoking GHC through Haddock. Critical for avoiding recompilation during documentation generation." + haddockNoVersionCPP + (\v flags -> flags{haddockNoVersionCPP = v}) + trueArg ] emptyHaddockFlags :: HaddockFlags @@ -410,8 +419,9 @@ data HaddockProjectFlags = HaddockProjectFlags haddockProjectKeepTempFiles :: Flag Bool , haddockProjectVerbosity :: Flag Verbosity , -- haddockBaseUrl is not supported, a fixed value is provided - haddockProjectLib :: Flag String + haddockProjectResourcesDir :: Flag String , haddockProjectOutputDir :: Flag FilePath + , haddockProjectNoVersionCPP :: Flag Bool } deriving (Show, Generic, Typeable) @@ -434,9 +444,10 @@ defaultHaddockProjectFlags = , haddockProjectHscolourCss = NoFlag , haddockProjectKeepTempFiles = Flag False , haddockProjectVerbosity = Flag normal - , haddockProjectLib = NoFlag + , haddockProjectResourcesDir = NoFlag , haddockProjectOutputDir = NoFlag , haddockProjectInterfaces = NoFlag + , haddockProjectNoVersionCPP = Flag False } haddockProjectCommand :: CommandUI HaddockProjectFlags @@ -578,10 +589,10 @@ haddockProjectOptions _showOrParseArgs = (\v flags -> flags{haddockProjectVerbosity = v}) , option "" - ["lib"] + ["resources-dir"] "location of Haddocks static / auxiliary files" - haddockProjectLib - (\v flags -> flags{haddockProjectLib = v}) + haddockProjectResourcesDir + (\v flags -> flags{haddockProjectResourcesDir = v}) (reqArgFlag "DIR") , option "" @@ -590,6 +601,13 @@ haddockProjectOptions _showOrParseArgs = haddockProjectOutputDir (\v flags -> flags{haddockProjectOutputDir = v}) (reqArgFlag "DIR") + , option + "" + ["no-version-cpp"] + "Do not define the __HADDOCK_VERSION__ macro when invoking GHC through Haddock. Critical for avoiding recompilation during documentation generation." + haddockProjectNoVersionCPP + (\v flags -> flags{haddockProjectNoVersionCPP = v}) + trueArg ] emptyHaddockProjectFlags :: HaddockProjectFlags diff --git a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs index d63e890a3ee..69a1fa6a542 100644 --- a/cabal-install/src/Distribution/Client/CmdHaddockProject.hs +++ b/cabal-install/src/Distribution/Client/CmdHaddockProject.hs @@ -144,8 +144,9 @@ haddockProjectAction flags _extraArgs globalFlags = do else NoFlag , haddockKeepTempFiles = haddockProjectKeepTempFiles flags , haddockVerbosity = haddockProjectVerbosity flags - , haddockLib = haddockProjectLib flags + , haddockResourcesDir = haddockProjectResourcesDir flags , haddockOutputDir = haddockProjectOutputDir flags + , haddockNoVersionCPP = haddockProjectNoVersionCPP flags } nixFlags = (commandDefaultFlags CmdHaddock.haddockCommand) diff --git a/cabal-install/src/Distribution/Client/Config.hs b/cabal-install/src/Distribution/Client/Config.hs index 24c6c6a29f4..3d132721c19 100644 --- a/cabal-install/src/Distribution/Client/Config.hs +++ b/cabal-install/src/Distribution/Client/Config.hs @@ -612,9 +612,10 @@ instance Semigroup SavedConfig where , haddockCabalFilePath = combine haddockCabalFilePath , haddockIndex = combine haddockIndex , haddockBaseUrl = combine haddockBaseUrl - , haddockLib = combine haddockLib + , haddockResourcesDir = combine haddockResourcesDir , haddockOutputDir = combine haddockOutputDir , haddockArgs = lastNonEmpty haddockArgs + , haddockNoVersionCPP = combine haddockNoVersionCPP } where combine = combine' savedHaddockFlags diff --git a/cabal-install/src/Distribution/Client/PackageHash.hs b/cabal-install/src/Distribution/Client/PackageHash.hs index 18be444cde7..5c842dfcbf8 100644 --- a/cabal-install/src/Distribution/Client/PackageHash.hs +++ b/cabal-install/src/Distribution/Client/PackageHash.hs @@ -234,8 +234,9 @@ data PackageHashConfigInputs = PackageHashConfigInputs , pkgHashHaddockContents :: Maybe PathTemplate , pkgHashHaddockIndex :: Maybe PathTemplate , pkgHashHaddockBaseUrl :: Maybe String - , pkgHashHaddockLib :: Maybe String + , pkgHashHaddockResourcesDir :: Maybe String , pkgHashHaddockOutputDir :: Maybe FilePath + , pkgHashHaddockNoVersionCPP :: Bool -- TODO: [required eventually] pkgHashToolsVersions ? -- TODO: [required eventually] pkgHashToolsExtraOptions ? } @@ -342,8 +343,9 @@ renderPackageHashInputs , opt "haddock-contents-location" Nothing (maybe "" fromPathTemplate) pkgHashHaddockContents , opt "haddock-index-location" Nothing (maybe "" fromPathTemplate) pkgHashHaddockIndex , opt "haddock-base-url" Nothing (fromMaybe "") pkgHashHaddockBaseUrl - , opt "haddock-lib" Nothing (fromMaybe "") pkgHashHaddockLib + , opt "haddock-resources-dir" Nothing (fromMaybe "") pkgHashHaddockResourcesDir , opt "haddock-output-dir" Nothing (fromMaybe "") pkgHashHaddockOutputDir + , opt "haddock-no-version-cpp" False prettyShow pkgHashHaddockNoVersionCPP ] ++ Map.foldrWithKey (\prog args acc -> opt (prog ++ "-options") [] unwords args : acc) [] pkgHashProgramArgs where diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs index 7814d6ef0ca..d6c8fe55a37 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Legacy.hs @@ -756,8 +756,9 @@ convertLegacyPerPackageFlags , haddockContents = packageConfigHaddockContents , haddockIndex = packageConfigHaddockIndex , haddockBaseUrl = packageConfigHaddockBaseUrl - , haddockLib = packageConfigHaddockLib + , haddockResourcesDir = packageConfigHaddockResourcesDir , haddockOutputDir = packageConfigHaddockOutputDir + , haddockNoVersionCPP = packageConfigHaddockNoVersionCPP } = haddockFlags TestFlags @@ -1145,9 +1146,10 @@ convertToLegacyPerPackageConfig PackageConfig{..} = , haddockCabalFilePath = mempty , haddockIndex = packageConfigHaddockIndex , haddockBaseUrl = packageConfigHaddockBaseUrl - , haddockLib = packageConfigHaddockLib + , haddockResourcesDir = packageConfigHaddockResourcesDir , haddockOutputDir = packageConfigHaddockOutputDir , haddockArgs = mempty + , haddockNoVersionCPP = packageConfigHaddockNoVersionCPP } testFlags = @@ -1550,8 +1552,9 @@ legacyPackageConfigFieldDescrs = , "index-location" , "keep-temp-files" , "base-url" - , "lib" + , "resources-dir" , "output-dir" + , "no-version-cpp" ] . commandOptionsToFields ) diff --git a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs index 744a50ddc37..1a39de86c99 100644 --- a/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectConfig/Types.hs @@ -297,8 +297,9 @@ data PackageConfig = PackageConfig , packageConfigHaddockContents :: Flag PathTemplate -- TODO: [required eventually] use this , packageConfigHaddockIndex :: Flag PathTemplate -- TODO: [required eventually] use this , packageConfigHaddockBaseUrl :: Flag String -- TODO: [required eventually] use this - , packageConfigHaddockLib :: Flag String -- TODO: [required eventually] use this + , packageConfigHaddockResourcesDir :: Flag String -- TODO: [required eventually] use this , packageConfigHaddockOutputDir :: Flag FilePath -- TODO: [required eventually] use this + , packageConfigHaddockNoVersionCPP :: Flag Bool -- TODO: [required eventually] use this , packageConfigHaddockForHackage :: Flag HaddockTarget , -- Test options packageConfigTestHumanLog :: Flag PathTemplate diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning.hs b/cabal-install/src/Distribution/Client/ProjectPlanning.hs index 10bf7c18cc7..961cb9a781d 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning.hs @@ -2202,6 +2202,13 @@ elaborateInstallPlan elabBuildHaddocks = perPkgOptionFlag pkgid False packageConfigDocumentation + -- `documentation: true` should imply `-haddock` for GHC + addHaddockIfDocumentationEnabled :: ConfiguredProgram -> ConfiguredProgram + addHaddockIfDocumentationEnabled cp@ConfiguredProgram{..} = + if programId == "ghc" && elabBuildHaddocks + then cp{programOverrideArgs = "-haddock" : programOverrideArgs} + else cp + elabPkgSourceLocation = srcloc elabPkgSourceHash = Map.lookup pkgid sourcePackageHashes elabLocalToProject = isLocalToProject pkg @@ -2274,7 +2281,7 @@ elaborateInstallPlan Map.fromList [ (programId prog, args) | prog <- configuredPrograms compilerprogdb - , let args = programOverrideArgs prog + , let args = programOverrideArgs $ addHaddockIfDocumentationEnabled prog , not (null args) ] <> perPkgOptionMapMappend pkgid packageConfigProgramArgs @@ -2303,8 +2310,9 @@ elaborateInstallPlan elabHaddockContents = perPkgOptionMaybe pkgid packageConfigHaddockContents elabHaddockIndex = perPkgOptionMaybe pkgid packageConfigHaddockIndex elabHaddockBaseUrl = perPkgOptionMaybe pkgid packageConfigHaddockBaseUrl - elabHaddockLib = perPkgOptionMaybe pkgid packageConfigHaddockLib + elabHaddockResourcesDir = perPkgOptionMaybe pkgid packageConfigHaddockResourcesDir elabHaddockOutputDir = perPkgOptionMaybe pkgid packageConfigHaddockOutputDir + elabHaddockNoVersionCPP = perPkgOptionFlag pkgid False packageConfigHaddockNoVersionCPP elabTestMachineLog = perPkgOptionMaybe pkgid packageConfigTestMachineLog elabTestHumanLog = perPkgOptionMaybe pkgid packageConfigTestHumanLog @@ -4453,9 +4461,10 @@ setupHsHaddockFlags (ElaboratedConfiguredPackage{..}) (ElaboratedSharedConfig{.. , haddockCabalFilePath = mempty , haddockIndex = maybe mempty toFlag elabHaddockIndex , haddockBaseUrl = maybe mempty toFlag elabHaddockBaseUrl - , haddockLib = maybe mempty toFlag elabHaddockLib + , haddockResourcesDir = maybe mempty toFlag elabHaddockResourcesDir , haddockOutputDir = maybe mempty toFlag elabHaddockOutputDir , haddockArgs = mempty + , haddockNoVersionCPP = toFlag elabHaddockNoVersionCPP } setupHsHaddockArgs :: ElaboratedConfiguredPackage -> [String] @@ -4622,8 +4631,9 @@ packageHashConfigInputs shared@ElaboratedSharedConfig{..} pkg = , pkgHashHaddockContents = elabHaddockContents , pkgHashHaddockIndex = elabHaddockIndex , pkgHashHaddockBaseUrl = elabHaddockBaseUrl - , pkgHashHaddockLib = elabHaddockLib + , pkgHashHaddockResourcesDir = elabHaddockResourcesDir , pkgHashHaddockOutputDir = elabHaddockOutputDir + , pkgHashHaddockNoVersionCPP = elabHaddockNoVersionCPP } where ElaboratedConfiguredPackage{..} = normaliseConfiguredPackage shared pkg diff --git a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs index 28af81774eb..9d5e70df6fe 100644 --- a/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs +++ b/cabal-install/src/Distribution/Client/ProjectPlanning/Types.hs @@ -309,8 +309,9 @@ data ElaboratedConfiguredPackage = ElaboratedConfiguredPackage , elabHaddockContents :: Maybe PathTemplate , elabHaddockIndex :: Maybe PathTemplate , elabHaddockBaseUrl :: Maybe String - , elabHaddockLib :: Maybe String + , elabHaddockResourcesDir :: Maybe String , elabHaddockOutputDir :: Maybe FilePath + , elabHaddockNoVersionCPP :: Bool , elabTestMachineLog :: Maybe PathTemplate , elabTestHumanLog :: Maybe PathTemplate , elabTestShowDetails :: Maybe TestShowDetails diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 680d4175c09..53b855b621e 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -2318,8 +2318,9 @@ haddockOptions showOrParseArgs = , "use-index" , "for-hackage" , "base-url" - , "lib" + , "resources-dir" , "output-dir" + , "no-version-cpp" ] ] diff --git a/cabal-install/tests/IntegrationTests2.hs b/cabal-install/tests/IntegrationTests2.hs index fd9ed4ca19d..f1460a003de 100644 --- a/cabal-install/tests/IntegrationTests2.hs +++ b/cabal-install/tests/IntegrationTests2.hs @@ -2095,7 +2095,9 @@ testConfigOptionComments = do " -- contents-location" @=? findLineWith True "contents-location" defaultConfigFile " -- index-location" @=? findLineWith True "index-location" defaultConfigFile " -- base-url" @=? findLineWith True "base-url" defaultConfigFile + " -- resources-dir" @=? findLineWith True "resources-dir" defaultConfigFile " -- output-dir" @=? findLineWith True "output-dir" defaultConfigFile + " -- no-version-cpp" @=? findLineWith True "no-version-cpp" defaultConfigFile " -- interactive" @=? findLineWith True "interactive" defaultConfigFile " -- quiet" @=? findLineWith True "quiet" defaultConfigFile diff --git a/cabal-install/tests/IntegrationTests2/config/default-config b/cabal-install/tests/IntegrationTests2/config/default-config index fab39496295..c1c4add2cc9 100644 --- a/cabal-install/tests/IntegrationTests2/config/default-config +++ b/cabal-install/tests/IntegrationTests2/config/default-config @@ -25,16 +25,16 @@ repository hackage.haskell.org -- store-dir: -- active-repositories: -- local-no-index-repo: -remote-repo-cache: /home/colton/.cabal/packages --- logs-dir: /home/colton/.cabal/logs +remote-repo-cache: /Users/finley/.cabal/packages +-- logs-dir: /Users/finley/.cabal/logs -- default-user-config: -- verbose: 1 -- compiler: ghc -- cabal-file: -- with-compiler: -- with-hc-pkg: --- program-prefix: --- program-suffix: +-- program-prefix: +-- program-suffix: -- library-vanilla: True -- library-profiling: -- shared: @@ -104,12 +104,13 @@ remote-repo-cache: /home/colton/.cabal/packages -- index-state: -- root-cmd: -- symlink-bindir: -build-summary: /home/colton/.cabal/logs/build.log +build-summary: /Users/finley/.cabal/logs/build.log -- build-log: remote-build-reporting: none -- report-planning-failure: False -- per-component: True -- run-tests: +-- semaphore: False jobs: $ncpus -- keep-going: False -- offline: False @@ -117,10 +118,11 @@ jobs: $ncpus -- package-env: -- overwrite-policy: -- install-method: -installdir: /home/colton/.cabal/bin +installdir: /Users/finley/.cabal/bin -- username: -- password: -- password-command: +-- multi-repl: -- builddir: haddock @@ -141,8 +143,9 @@ haddock -- contents-location: -- index-location: -- base-url: - -- lib: + -- resources-dir: -- output-dir: + -- no-version-cpp: False init -- interactive: False @@ -160,7 +163,7 @@ init -- source-dir: src install-dirs user - -- prefix: /home/colton/.cabal + -- prefix: /Users/finley/.cabal -- bindir: $prefix/bin -- libdir: $prefix/lib -- libsubdir: $abi/$libname diff --git a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs index cdb34a3534c..9ed1206d117 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs @@ -725,6 +725,7 @@ instance Arbitrary PackageConfig where <*> arbitrary <*> arbitrary <*> arbitrary + <*> arbitrary <*> arbitraryFlag arbitraryShortToken <*> arbitrary <*> shortListOf 5 arbitrary @@ -790,8 +791,9 @@ instance Arbitrary PackageConfig where , packageConfigHaddockForHackage = x41 , packageConfigHaddockIndex = x54 , packageConfigHaddockBaseUrl = x55 - , packageConfigHaddockLib = x56 + , packageConfigHaddockResourcesDir = x56 , packageConfigHaddockOutputDir = x57 + , packageConfigHaddockNoVersionCPP = x58 , packageConfigTestHumanLog = x44 , packageConfigTestMachineLog = x45 , packageConfigTestShowDetails = x46 @@ -853,8 +855,9 @@ instance Arbitrary PackageConfig where , packageConfigHaddockForHackage = x41' , packageConfigHaddockIndex = x54' , packageConfigHaddockBaseUrl = x55' - , packageConfigHaddockLib = x56' + , packageConfigHaddockResourcesDir = x56' , packageConfigHaddockOutputDir = x57' + , packageConfigHaddockNoVersionCPP = x58' , packageConfigTestHumanLog = x44' , packageConfigTestMachineLog = x45' , packageConfigTestShowDetails = x46' @@ -877,6 +880,7 @@ instance Arbitrary PackageConfig where , (x44', x45', x46', x47', x48', x49', x51', x52', x54', x55') , x56' , x57' + , x58' ) ) <- shrink @@ -902,6 +906,7 @@ instance Arbitrary PackageConfig where , (x44, x45, x46, x47, x48, x49, x51, x52, x54, x55) , x56 , x57 + , x58 ) ) ] diff --git a/cabal-testsuite/PackageTests/NewHaddock/Fails/cabal.out b/cabal-testsuite/PackageTests/NewHaddock/Fails/cabal.out index 85f6c8b8d46..433103b5566 100644 --- a/cabal-testsuite/PackageTests/NewHaddock/Fails/cabal.out +++ b/cabal-testsuite/PackageTests/NewHaddock/Fails/cabal.out @@ -10,7 +10,8 @@ Error: cabal: Failed to build example-1.0-inplace. # cabal v2-haddock Build profile: -w ghc- -O1 In order, the following will be built: - - example-1.0 (lib) (first run) + - example-1.0 (lib) (configuration changed) +Configuring library for example-1.0... Preprocessing library for example-1.0... Running Haddock on library for example-1.0... Error: cabal: Failed to build documentation for example-1.0-inplace. diff --git a/changelog.d/pr-9177 b/changelog.d/pr-9177 new file mode 100644 index 00000000000..e4a56141802 --- /dev/null +++ b/changelog.d/pr-9177 @@ -0,0 +1,26 @@ +synopsis: Enable recompilation avoidance during Haddock generation +packages: cabal-install +prs: #9177 +issues: #9175 + +description: { + +* Haddock no longer writes compilation files by default, so we do not need to + pass tmp dirs for `-hidir`, `-stubdir`, and `-odir` via `--optghc`. Indeed, we + do not *want* to do so, since it results in recompilation for every invocation + of Haddock via Cabal. We now stop this from happening. + +* Introduce the `--no-haddock-version-cpp` flag and `no-haddock-version-cpp:` + cabal.project field, which prevent the definition of the `__HADDOCK_VERSION__` + macro when invoking GHC through Haddock. This is essentially required in order + for Haddock to be able to use existing compilation results and avoid + recompilation, since the macro definition will trigger recompilation. + +* Rename the `--haddock-lib` flag to `--haddock-resources-dir` (and + `haddock-lib:` cabal.project field to `haddock-resources-dir:`), and add this + flag to the users guide since it was missing an entry. + +* `documentation: true` or `--enable-documentation` now implies `-haddock` for + GHC. + +} \ No newline at end of file diff --git a/doc/cabal-project.rst b/doc/cabal-project.rst index 90f819a529c..2f8e1397b5c 100644 --- a/doc/cabal-project.rst +++ b/doc/cabal-project.rst @@ -1543,6 +1543,25 @@ running ``setup haddock``. This flag is provided as a technology preview and is subject to change in the next releases. +.. cfg-field:: haddock-resources-dir: DIR + --haddock-resources-dir=DIR + :synopsis: Location of Haddock's static/auxiliary files. + + Location of Haddock's static/auxiliary files. For Haddock distributed with + GHC (or, more precisely, built within the GHC source tree), this path should + be automatically inferred. For Haddock built from source, however, this path + should likely be explicitly set for every Haddock invocation. + +.. cfg-field:: haddock-no-version-cpp: boolean + --haddock-no-version-cpp + :synopsis: Do not define the ``__HADDOCK_VERSION__`` macro when invoking GHC + through Haddock. + + Do not define the ``__HADDOCK_VERSION__`` macro when invoking GHC through + Haddock. This is critical for avoiding recompilation during documentation + generation, since such a macro definition will trigger recompilation if the + interface files on disk were compiled without it, as they likely were. + .. cfg-field:: open: boolean --open :synopsis: Open generated documentation in-browser. diff --git a/test/IntegrationTests2/config/default-config b/test/IntegrationTests2/config/default-config index 8e3aa02742c..c3af06d572c 100644 --- a/test/IntegrationTests2/config/default-config +++ b/test/IntegrationTests2/config/default-config @@ -33,8 +33,8 @@ remote-repo-cache: /home/colton/.cabal/packages -- cabal-file: -- with-compiler: -- with-hc-pkg: --- program-prefix: --- program-suffix: +-- program-prefix: +-- program-suffix: -- library-vanilla: True -- library-profiling: -- shared: @@ -141,8 +141,9 @@ haddock -- contents-location: -- index-location: -- base-url: - -- lib: + -- resources-dir: -- output-dir: + -- no-version-cpp: False init -- interactive: False diff --git a/test/IntegrationTests2/nix-config/default-config b/test/IntegrationTests2/nix-config/default-config index 8e3aa02742c..c3af06d572c 100644 --- a/test/IntegrationTests2/nix-config/default-config +++ b/test/IntegrationTests2/nix-config/default-config @@ -33,8 +33,8 @@ remote-repo-cache: /home/colton/.cabal/packages -- cabal-file: -- with-compiler: -- with-hc-pkg: --- program-prefix: --- program-suffix: +-- program-prefix: +-- program-suffix: -- library-vanilla: True -- library-profiling: -- shared: @@ -141,8 +141,9 @@ haddock -- contents-location: -- index-location: -- base-url: - -- lib: + -- resources-dir: -- output-dir: + -- no-version-cpp: False init -- interactive: False diff --git a/tests/IntegrationTests2/config/default-config b/tests/IntegrationTests2/config/default-config index 8e3aa02742c..c1c4add2cc9 100644 --- a/tests/IntegrationTests2/config/default-config +++ b/tests/IntegrationTests2/config/default-config @@ -25,16 +25,16 @@ repository hackage.haskell.org -- store-dir: -- active-repositories: -- local-no-index-repo: -remote-repo-cache: /home/colton/.cabal/packages --- logs-dir: /home/colton/.cabal/logs +remote-repo-cache: /Users/finley/.cabal/packages +-- logs-dir: /Users/finley/.cabal/logs -- default-user-config: -- verbose: 1 -- compiler: ghc -- cabal-file: -- with-compiler: -- with-hc-pkg: --- program-prefix: --- program-suffix: +-- program-prefix: +-- program-suffix: -- library-vanilla: True -- library-profiling: -- shared: @@ -63,7 +63,7 @@ remote-repo-cache: /home/colton/.cabal/packages -- extra-lib-dirs: -- extra-lib-dirs-static: -- extra-framework-dirs: -extra-prog-path: /home/colton/.cabal/bin +-- extra-prog-path: -- instantiate-with: -- tests: False -- coverage: False @@ -104,12 +104,13 @@ extra-prog-path: /home/colton/.cabal/bin -- index-state: -- root-cmd: -- symlink-bindir: -build-summary: /home/colton/.cabal/logs/build.log +build-summary: /Users/finley/.cabal/logs/build.log -- build-log: remote-build-reporting: none -- report-planning-failure: False -- per-component: True -- run-tests: +-- semaphore: False jobs: $ncpus -- keep-going: False -- offline: False @@ -117,10 +118,11 @@ jobs: $ncpus -- package-env: -- overwrite-policy: -- install-method: -installdir: /home/colton/.cabal/bin +installdir: /Users/finley/.cabal/bin -- username: -- password: -- password-command: +-- multi-repl: -- builddir: haddock @@ -141,8 +143,9 @@ haddock -- contents-location: -- index-location: -- base-url: - -- lib: + -- resources-dir: -- output-dir: + -- no-version-cpp: False init -- interactive: False @@ -160,7 +163,7 @@ init -- source-dir: src install-dirs user - -- prefix: /home/colton/.cabal + -- prefix: /Users/finley/.cabal -- bindir: $prefix/bin -- libdir: $prefix/lib -- libsubdir: $abi/$libname diff --git a/tests/IntegrationTests2/nix-config/default-config b/tests/IntegrationTests2/nix-config/default-config index 8e3aa02742c..c3af06d572c 100644 --- a/tests/IntegrationTests2/nix-config/default-config +++ b/tests/IntegrationTests2/nix-config/default-config @@ -33,8 +33,8 @@ remote-repo-cache: /home/colton/.cabal/packages -- cabal-file: -- with-compiler: -- with-hc-pkg: --- program-prefix: --- program-suffix: +-- program-prefix: +-- program-suffix: -- library-vanilla: True -- library-profiling: -- shared: @@ -141,8 +141,9 @@ haddock -- contents-location: -- index-location: -- base-url: - -- lib: + -- resources-dir: -- output-dir: + -- no-version-cpp: False init -- interactive: False