From 4e7340595584b45c49f62ee270aa68de782e07aa Mon Sep 17 00:00:00 2001 From: Alp Mestanogullari Date: Wed, 27 Feb 2019 17:23:48 +0100 Subject: Hadrian: introduce ways to skip some documentation targets The initial motivation for this is to have a chance to run the binary distribution rules in our Windows CI without having to install sphinx-build and xelatex there, while retaining the ability to generate haddocks. I just ended up extending this idea a little bit so as to have control over whether we build haddocks, (sphinx) HTML manuals, (sphinx) PDF manuals and (sphinx) manpages. (cherry picked from commit 8442103aa575dc1cd25cb3231e729c6365dc1b5c) --- hadrian/doc/make.md | 16 ++++++++++++++ hadrian/doc/user-settings.md | 44 +++++++++++++++++++++++++++++++++++++- hadrian/src/CommandLine.hs | 35 +++++++++++++++++++++++++++--- hadrian/src/Flavour.hs | 31 +++++++++++++++++++++++++-- hadrian/src/Rules/Documentation.hs | 39 +++++++++++++++++++++++++++++++-- hadrian/src/Settings/Default.hs | 3 ++- 6 files changed, 159 insertions(+), 9 deletions(-) diff --git a/hadrian/doc/make.md b/hadrian/doc/make.md index 0d9bb911b4..15bd6bd799 100644 --- a/hadrian/doc/make.md +++ b/hadrian/doc/make.md @@ -174,6 +174,22 @@ time you fire up a build. This is not possible with the Make build system. build docs ``` +- Build documentation, but without haddocks (resp. without HTML or PDF manuals) + + ``` sh + # Make + echo 'HADDOCKS_DOCS = NO' > mk/build.mk + # For HTML manuals: BUILD_SPHINX_HTML = NO + # For PDF manuals: BUILD_SPHINX_PDF = NO + make + + # Hadrian + build docs --docs=no-haddocks + # Append --docs=no-sphinx-pdfs, --docs=no-sphinx-html or + # --docs=no-sphinx-man (or --docs=no-sphinx to encompass them all) + # to further reduce or even completely disable documentation targets. + ``` + - Running nofib ``` sh diff --git a/hadrian/doc/user-settings.md b/hadrian/doc/user-settings.md index 690104c776..8f7062730a 100644 --- a/hadrian/doc/user-settings.md +++ b/hadrian/doc/user-settings.md @@ -32,7 +32,10 @@ data Flavour = Flavour { -- | Build profiled GHC. ghcProfiled :: Bool, -- | Build GHC with debug information. - ghcDebugged :: Bool } + ghcDebugged :: Bool + -- | Whether to build docs and which ones + -- (haddocks, user manual, haddock manual) + ghcDocs :: Action DocTargets } ``` Hadrian provides several built-in flavours (`default`, `quick`, and a few others; see `hadrian/doc/flavours.md`), which can be activated from the command line, @@ -227,6 +230,45 @@ verboseCommand = output "//rts/sm/*" &&^ way threaded verboseCommand = return True ``` +## Documentation + +`Flavour`'s `ghcDocs :: Action DocTargets` field lets you +customize the "groups" of documentation targets that should +run when running `build docs` (or, transitively, +`build binary-dist`). + +```haskell +type DocTargets = Set DocTarget +data DocTarget = Haddocks | SphinxHTML | SphinxPDFs | SphinxMan +``` + +By default, `ghcDocs` contains all of them and `build docs` would +therefore attempt to build all the haddocks, manuals and manpages. +If, for some reason (e.g no easy way to install `sphinx-build` or +`xelatex` on your system), you're just interested in building the +haddocks, you could define a custom flavour as follows: + +```haskell +justHaddocksFlavour :: Flavour +justHaddocksFlavour = defaultFlavour + { name = "default-haddocks" + , ghcDocs = Set.singleton Haddocks } +``` + +and then run `build --flavour=default-haddocks`. Alternatively, +you can use the `--docs` CLI flag to selectively disable some or +all of the documentation targets: + +- `--docs=none`: don't build any docs +- `--docs=no-haddocks`: don't build haddocks +- `--docs=no-sphinx`: don't build any user manual or manpage +- `--docs=no-sphinx-html`: don't build HTML versions of manuals +- `--docs=no-sphinx-pdfs`: don't build PDF versions of manuals +- `--docs=no-sphinx-man`: don't build the manpage + +You can pass several `--docs=...` flags, Hadrian will combine +their effects. + ## Miscellaneous To change the default behaviour of Hadrian with respect to building split diff --git a/hadrian/src/CommandLine.hs b/hadrian/src/CommandLine.hs index 1f940f2152..842fb037cc 100644 --- a/hadrian/src/CommandLine.hs +++ b/hadrian/src/CommandLine.hs @@ -1,17 +1,20 @@ module CommandLine ( optDescrs, cmdLineArgsMap, cmdFlavour, lookupFreeze1, cmdIntegerSimple, cmdProgressColour, cmdProgressInfo, cmdConfigure, cmdSplitObjects, - lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs + cmdDocsArgs, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs ) where import Data.Either import qualified Data.HashMap.Strict as Map import Data.List.Extra import Development.Shake hiding (Normal) +import Flavour (DocTargets, DocTarget(..)) import Hadrian.Utilities hiding (buildRoot) import System.Console.GetOpt import System.Environment +import qualified Data.Set as Set + data TestSpeed = Slow | Average | Fast deriving (Show, Eq) -- | All arguments that can be passed to Hadrian via the command line. @@ -24,7 +27,8 @@ data CommandLineArgs = CommandLineArgs , progressInfo :: ProgressInfo , splitObjects :: Bool , buildRoot :: BuildRoot - , testArgs :: TestArgs } + , testArgs :: TestArgs + , docTargets :: DocTargets } deriving (Eq, Show) -- | Default values for 'CommandLineArgs'. @@ -38,7 +42,8 @@ defaultCommandLineArgs = CommandLineArgs , progressInfo = Brief , splitObjects = False , buildRoot = BuildRoot "_build" - , testArgs = defaultTestArgs } + , testArgs = defaultTestArgs + , docTargets = Set.fromList [minBound..maxBound] } -- | These arguments are used by the `test` target. data TestArgs = TestArgs @@ -179,6 +184,25 @@ readTestWay way = let newWays = way : testWays (testArgs flags) in flags { testArgs = (testArgs flags) {testWays = newWays} } +readDocsArg :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs) +readDocsArg ms = maybe (Left "Cannot parse docs argument") (Right . set) (go =<< ms) + + where + go :: String -> Maybe (DocTargets -> DocTargets) + go "none" = Just (const Set.empty) + go "no-haddocks" = Just (Set.delete Haddocks) + go "no-sphinx-html" = Just (Set.delete SphinxHTML) + go "no-sphinx-pdfs" = Just (Set.delete SphinxPDFs) + go "no-sphinx-man" = Just (Set.delete SphinxMan) + go "no-sphinx" = Just (Set.delete SphinxHTML + . Set.delete SphinxPDFs + . Set.delete SphinxMan) + go _ = Nothing + + set :: (DocTargets -> DocTargets) -> CommandLineArgs -> CommandLineArgs + set tweakTargets flags = flags + { docTargets = tweakTargets (docTargets flags) } + -- | Standard 'OptDescr' descriptions of Hadrian's command line arguments. optDescrs :: [OptDescr (Either String (CommandLineArgs -> CommandLineArgs))] optDescrs = @@ -198,6 +222,8 @@ optDescrs = "Progress info style (None, Brief, Normal or Unicorn)." , Option [] ["split-objects"] (NoArg readSplitObjects) "Generate split objects (requires a full clean rebuild)." + , Option [] ["docs"] (OptArg readDocsArg "TARGET") + "Strip down docs targets (none, no-haddocks, no-sphinx[-{html, pdfs, man}]." , Option [] ["test-compiler"] (OptArg readTestCompiler "TEST_COMPILER") "Use given compiler [Default=stage2]." , Option [] ["test-config-file"] (OptArg readTestConfigFile "CONFIG_FILE") @@ -259,3 +285,6 @@ cmdProgressInfo = progressInfo <$> cmdLineArgs cmdSplitObjects :: Action Bool cmdSplitObjects = splitObjects <$> cmdLineArgs + +cmdDocsArgs :: Action DocTargets +cmdDocsArgs = docTargets <$> cmdLineArgs diff --git a/hadrian/src/Flavour.hs b/hadrian/src/Flavour.hs index 23e2aa8a81..4a71e80c45 100644 --- a/hadrian/src/Flavour.hs +++ b/hadrian/src/Flavour.hs @@ -1,6 +1,10 @@ -module Flavour (Flavour (..), werror) where +module Flavour + ( Flavour (..), werror + , DocTargets, DocTarget(..) + ) where import Expression +import Data.Set (Set) -- Please update doc/{flavours.md, user-settings.md} when changing this file. -- | 'Flavour' is a collection of build settings that fully define a GHC build. @@ -31,8 +35,31 @@ data Flavour = Flavour { -- | Build profiled GHC. ghcProfiled :: Bool, -- | Build GHC with debug information. - ghcDebugged :: Bool } + ghcDebugged :: Bool, + -- | Whether to build docs and which ones + -- (haddocks, user manual, haddock manual) + ghcDocs :: Action DocTargets } +-- | A set of documentation targets +type DocTargets = Set DocTarget + +-- | Documentation targets +-- +-- While we can't reasonably expose settings or CLI options +-- to selectively disable, say, base's haddocks, we can offer +-- a less fine-grained choice: +-- +-- - haddocks for libraries +-- - non-haddock html pages (e.g GHC's user manual) +-- - PDF documents (e.g haddock's manual) +-- - man pages (GHC's) +-- +-- The main goal being to have easy ways to do away with the need +-- for e.g @sphinx-build@ or @xelatex@ and associated packages +-- while still being able to build a(n almost) complete binary +-- distribution. +data DocTarget = Haddocks | SphinxHTML | SphinxPDFs | SphinxMan + deriving (Eq, Ord, Show, Bounded, Enum) -- | Turn on -Werror for packages built with the stage1 compiler. -- It mimics the CI settings so is useful to turn on when developing. diff --git a/hadrian/src/Rules/Documentation.hs b/hadrian/src/Rules/Documentation.hs index 2d7a4b1ef7..d9a506ca89 100644 --- a/hadrian/src/Rules/Documentation.hs +++ b/hadrian/src/Rules/Documentation.hs @@ -22,6 +22,7 @@ import Target import Utilities import Data.List (union) +import qualified Data.Set as Set import qualified Text.Parsec as Parsec docRoot :: FilePath @@ -79,10 +80,35 @@ documentationRules = do -- Haddock's manual, and builds man pages "docs" ~> do root <- buildRoot + doctargets <- ghcDocs =<< flavour let html = htmlRoot -/- "index.html" -- also implies "docs-haddock" archives = map pathArchive docPaths pdfs = map pathPdf $ docPaths \\ ["libraries"] - need $ map (root -/-) $ [html] ++ archives ++ pdfs ++ [manPageBuildPath] + + targets = -- include PDFs unless --docs=no-sphinx[-pdf] is + -- passed. + concat [ pdfs | SphinxPDFs `Set.member` doctargets ] + + -- include manpage unless --docs=no-sphinx[-man] is given. + ++ [ manPageBuildPath | SphinxMan `Set.member` doctargets ] + + -- include toplevel html target uness we neither want + -- haddocks nor html pages produced by sphinx. + ++ [ html | Set.size (doctargets `Set.intersection` + Set.fromList [Haddocks, SphinxHTML] + ) > 0 ] + + -- include archives for whatever targets remain from + -- the --docs arguments we got. + ++ [ ar + | (ar, doc) <- zip archives docPaths + , archiveTarget doc `Set.member` doctargets ] + + need $ map (root -/-) targets + + where archiveTarget "libraries" = Haddocks + archiveTarget _ = SphinxHTML + ------------------------------------- HTML ------------------------------------- @@ -94,7 +120,16 @@ buildHtmlDocumentation = do root <- buildRootRules root -/- htmlRoot -/- "index.html" %> \file -> do - need $ map ((root -/-) . pathIndex) docPaths + doctargets <- ghcDocs =<< flavour + + -- We include the HTML output of haddock for libraries unless + -- told not to (e.g with --docs=no-haddocks). Likewise for + -- the HTML version of the users guide or the Haddock manual. + let targets = [ "libraries" | Haddocks `Set.member` doctargets ] + ++ concat [ ["users_guide", "Haddock"] + | SphinxHTML `Set.member` doctargets ] + need $ map ((root -/-) . pathIndex) targets + copyFileUntracked "docs/index.html" file -- | Compile a Sphinx ReStructured Text package to HTML. diff --git a/hadrian/src/Settings/Default.hs b/hadrian/src/Settings/Default.hs index e2d7644beb..e9dd213f92 100644 --- a/hadrian/src/Settings/Default.hs +++ b/hadrian/src/Settings/Default.hs @@ -222,7 +222,8 @@ defaultFlavour = Flavour , dynamicGhcPrograms = defaultDynamicGhcPrograms , ghciWithDebugger = False , ghcProfiled = False - , ghcDebugged = False } + , ghcDebugged = False + , ghcDocs = cmdDocsArgs } -- | Default logic for determining whether to build -- dynamic GHC programs. -- cgit v1.2.1