b8570a3c2e2019b4cc48f221ee798750835b0759
[hadrian.git] / src / Rules / Documentation.hs
1 module Rules.Documentation (
2 -- * Rules
3 buildPackageDocumentation, documentationRules,
4
5 -- * Utilities
6 haddockDependencies
7 ) where
8
9 import Base
10 import Context
11 import Flavour
12 import GHC
13 import Oracles.ModuleFiles
14 import Oracles.PackageData
15 import Settings
16 import Target
17 import Utilities
18
19 -- | Build all documentation
20 documentationRules :: Rules ()
21 documentationRules = do
22 buildHtmlDocumentation
23 buildPdfDocumentation
24 buildDocumentationArchives
25 buildManPage
26 "//docs//gen_contents_index" %> copyFile "libraries/gen_contents_index"
27 "//docs//prologue.txt" %> copyFile "libraries/prologue.txt"
28 "docs" ~> do
29 root <- buildRoot
30 let html = htmlRoot -/- "index.html"
31 archives = map pathArchive docPaths
32 pdfs = map pathPdf $ docPaths \\ [ "libraries" ]
33 need $ map (root -/-) $ [html] ++ archives ++ pdfs
34 need [ root -/- htmlRoot -/- "libraries" -/- "gen_contents_index" ]
35 need [ root -/- htmlRoot -/- "libraries" -/- "prologue.txt" ]
36 need [manPagePath]
37
38 manPagePath :: FilePath
39 manPagePath = "_build/docs/users_guide/build-man/ghc.1"
40
41 -- TODO: Add support for Documentation Packages so we can
42 -- run the builders without this hack.
43 docPackage :: Package
44 docPackage = hsLibrary "Documentation" "docs"
45
46 docPaths :: [FilePath]
47 docPaths = [ "libraries", "users_guide", "Haddock" ]
48
49 docRoot :: FilePath
50 docRoot = "docs"
51
52 htmlRoot :: FilePath
53 htmlRoot = docRoot -/- "html"
54
55 pdfRoot :: FilePath
56 pdfRoot = docRoot -/- "pdfs"
57
58 archiveRoot :: FilePath
59 archiveRoot = docRoot -/- "archives"
60
61 pathPdf :: FilePath -> FilePath
62 pathPdf path = pdfRoot -/- path <.> ".pdf"
63
64 pathIndex :: FilePath -> FilePath
65 pathIndex path = htmlRoot -/- path -/- "index.html"
66
67 pathArchive :: FilePath -> FilePath
68 pathArchive path = archiveRoot -/- path <.> "html.tar.xz"
69
70 -- TODO: Replace this with pkgPath when support is added
71 -- for Documentation Packages.
72 pathPath :: FilePath -> FilePath
73 pathPath "users_guide" = "docs/users_guide"
74 pathPath "Haddock" = "utils/haddock/doc"
75 pathPath _ = ""
76
77 ----------------------------------------------------------------------
78 -- HTML
79
80 -- | Build all HTML documentation
81 buildHtmlDocumentation :: Rules ()
82 buildHtmlDocumentation = do
83 mapM_ buildSphinxHtml $ docPaths \\ [ "libraries" ]
84 buildLibraryDocumentation
85 "//" ++ htmlRoot -/- "index.html" %> \file -> do
86 root <- buildRoot
87 need $ map ((root -/-) . pathIndex) docPaths
88 copyFileUntracked "docs/index.html" file
89
90 -----------------------------
91 -- Sphinx
92
93 -- | Compile a Sphinx ReStructured Text package to HTML
94 buildSphinxHtml :: FilePath -> Rules ()
95 buildSphinxHtml path = do
96 "//" ++ htmlRoot -/- path -/- "index.html" %> \file -> do
97 let dest = takeDirectory file
98 context = vanillaContext Stage0 docPackage
99 build $ target context (Sphinx Html) [pathPath path] [dest]
100
101 -----------------------------
102 -- Haddock
103
104 -- | Build the haddocks for GHC's libraries
105 buildLibraryDocumentation :: Rules ()
106 buildLibraryDocumentation = do
107 "//" ++ htmlRoot -/- "libraries/index.html" %> \file -> do
108 haddocks <- allHaddocks
109 need haddocks
110 let libDocs = filter (\x -> takeFileName x /= "ghc.haddock") haddocks
111 context = vanillaContext Stage2 docPackage
112 build $ target context (Haddock BuildIndex) libDocs [file]
113
114 allHaddocks :: Action [FilePath]
115 allHaddocks = do
116 pkgs <- stagePackages Stage1
117 sequence [ pkgHaddockFile $ vanillaContext Stage1 pkg
118 | pkg <- pkgs, isLibrary pkg, isHsPackage pkg ]
119
120 -- | Find the haddock files for the dependencies of the current library
121 haddockDependencies :: Context -> Action [FilePath]
122 haddockDependencies context = do
123 path <- buildPath context
124 depNames <- pkgDataList $ DepNames path
125 sequence [ pkgHaddockFile $ vanillaContext Stage1 depPkg
126 | Just depPkg <- map findPackageByName depNames, depPkg /= rts ]
127
128 -- Note: this build rule creates plenty of files, not just the .haddock one.
129 -- All of them go into the 'doc' subdirectory. Pedantically tracking all built
130 -- files in the Shake database seems fragile and unnecessary.
131 buildPackageDocumentation :: Context -> Rules ()
132 buildPackageDocumentation context@Context {..} = when (stage == Stage1) $ do
133
134 -- Js and Css files for haddock output
135 when (package == haddock) $ haddockHtmlResourcesStamp %> \_ -> do
136 let dir = takeDirectory haddockHtmlResourcesStamp
137 liftIO $ removeFiles dir ["//*"]
138 copyDirectory "utils/haddock/haddock-api/resources/html" dir
139
140 -- Per-package haddocks
141 "//" ++ pkgName package <.> "haddock" %> \file -> do
142 haddocks <- haddockDependencies context
143 srcs <- hsSources context
144 need $ srcs ++ haddocks
145
146 -- Build Haddock documentation
147 -- TODO: pass the correct way from Rules via Context
148 dynamicPrograms <- dynamicGhcPrograms <$> flavour
149 let haddockWay = if dynamicPrograms then dynamic else vanilla
150 build $ target (context {way = haddockWay}) (Haddock BuildPackage)
151 srcs [file]
152
153 ----------------------------------------------------------------------
154 -- PDF
155
156 -- | Build all PDF documentation
157 buildPdfDocumentation :: Rules ()
158 buildPdfDocumentation = mapM_ buildSphinxPdf docPaths
159
160 -- | Compile a Sphinx ReStructured Text package to LaTeX
161 buildSphinxPdf :: FilePath -> Rules ()
162 buildSphinxPdf path = do
163 "//" ++ path <.> "pdf" %> \file -> do
164 let context = vanillaContext Stage0 docPackage
165 withTempDir $ \dir -> do
166 build $ target context (Sphinx Latex) [pathPath path] [dir]
167 build $ target context Xelatex [path <.> "tex"] [dir]
168 copyFileUntracked (dir -/- path <.> "pdf") file
169
170 ----------------------------------------------------------------------
171 -- Archive
172
173 -- | Build archives of documentation
174 buildDocumentationArchives :: Rules ()
175 buildDocumentationArchives = mapM_ buildArchive docPaths
176
177 buildArchive :: FilePath -> Rules ()
178 buildArchive path = do
179 "//" ++ pathArchive path %> \file -> do
180 root <- buildRoot
181 let context = vanillaContext Stage0 docPackage
182 src = root -/- pathIndex path
183 need [src]
184 build $ target context (Tar Create) [takeDirectory src] [file]
185
186 -- | build man page
187 buildManPage :: Rules ()
188 buildManPage = do
189 manPagePath %> \file -> do
190 need ["docs/users_guide/ghc.rst"]
191 let context = vanillaContext Stage0 docPackage
192 withTempDir $ \dir -> do
193 build $ target context (Sphinx Man) ["docs/users_guide"] [dir]
194 copyFileUntracked (dir -/- "ghc.1") file