7a9ff5608a05d9e9387ba7f4c5b5ffee8dedba7b
[hadrian.git] / src / GHC.hs
1 {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
2 module GHC (
3 -- * GHC packages
4 array, base, binary, bytestring, cabal, checkApiAnnotations, compareSizes,
5 compiler, containers, deepseq, deriveConstants, directory, dllSplit, filepath,
6 genapply, genprimopcode, ghc, ghcBoot, ghcBootTh, ghcCabal, ghcCompact, ghci,
7 ghcPkg, ghcPrim, ghcTags, ghcSplit, haddock, haskeline, hsc2hs, hp2ps,
8 hpc, hpcBin, integerGmp, integerSimple, iservBin, libffi, mtl, parsec,
9 parallel, pretty, primitive, process, rts, runGhc, stm, templateHaskell,
10 terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml,
11 ghcPackages, isGhcPackage, defaultPackages,
12
13 -- * Package information
14 programName, nonCabalContext, nonHsMainPackage, autogenPath, installStage,
15
16 -- * Miscellaneous
17 programPath, ghcSplitPath, stripCmdPath, buildDll0
18 ) where
19
20 import Base
21 import CommandLine
22 import Context
23 import Oracles.Setting
24
25 -- | These are all GHC packages we know about. Build rules will be generated for
26 -- all of them. However, not all of these packages will be built. For example,
27 -- package 'win32' is built only on Windows. 'defaultPackages' defines default
28 -- conditions for building each package. Users can add their own packages and
29 -- modify build default build conditions in "UserSettings".
30 ghcPackages :: [Package]
31 ghcPackages =
32 [ array, base, binary, bytestring, cabal, checkApiAnnotations, compareSizes
33 , compiler, containers, deepseq, deriveConstants, directory, dllSplit
34 , filepath, genapply, genprimopcode, ghc, ghcBoot, ghcBootTh, ghcCabal
35 , ghcCompact, ghci, ghcPkg, ghcPrim, ghcTags, haddock, haskeline, hsc2hs
36 , hp2ps, hpc, hpcBin, integerGmp, integerSimple, iservBin, libffi
37 , mtl, parsec, parallel, pretty, primitive, process, rts, runGhc, stm
38 , templateHaskell, terminfo, text, time, touchy, transformers, unlit, unix
39 , win32, xhtml ]
40
41 -- TODO: Optimise by switching to sets of packages.
42 isGhcPackage :: Package -> Bool
43 isGhcPackage = (`elem` ghcPackages)
44
45 -- | Package definitions, see 'Package'.
46 array = hsLib "array"
47 base = hsLib "base"
48 binary = hsLib "binary"
49 bytestring = hsLib "bytestring"
50 cabal = hsLib "Cabal" `setPath` "libraries/Cabal/Cabal"
51 checkApiAnnotations = hsUtil "check-api-annotations"
52 compareSizes = hsUtil "compareSizes" `setPath` "utils/compare_sizes"
53 compiler = hsTop "ghc" `setPath` "compiler"
54 containers = hsLib "containers"
55 deepseq = hsLib "deepseq"
56 deriveConstants = hsUtil "deriveConstants"
57 directory = hsLib "directory"
58 dllSplit = hsUtil "dll-split"
59 filepath = hsLib "filepath"
60 genapply = hsUtil "genapply"
61 genprimopcode = hsUtil "genprimopcode"
62 ghc = hsPrg "ghc-bin" `setPath` "ghc"
63 ghcBoot = hsLib "ghc-boot"
64 ghcBootTh = hsLib "ghc-boot-th"
65 ghcCabal = hsUtil "ghc-cabal"
66 ghcCompact = hsLib "ghc-compact"
67 ghci = hsLib "ghci"
68 ghcPkg = hsUtil "ghc-pkg"
69 ghcPrim = hsLib "ghc-prim"
70 ghcTags = hsUtil "ghctags"
71 ghcSplit = hsUtil "ghc-split"
72 haddock = hsUtil "haddock"
73 haskeline = hsLib "haskeline"
74 hsc2hs = hsUtil "hsc2hs"
75 hp2ps = cUtil "hp2ps"
76 hpc = hsLib "hpc"
77 hpcBin = hsUtil "hpc-bin" `setPath` "utils/hpc"
78 integerGmp = hsLib "integer-gmp"
79 integerSimple = hsLib "integer-simple"
80 iservBin = hsPrg "iserv-bin" `setPath` "iserv"
81 libffi = cTop "libffi"
82 mtl = hsLib "mtl"
83 parsec = hsLib "parsec"
84 parallel = hsLib "parallel"
85 pretty = hsLib "pretty"
86 primitive = hsLib "primitive"
87 process = hsLib "process"
88 rts = cTop "rts"
89 runGhc = hsUtil "runghc"
90 stm = hsLib "stm"
91 templateHaskell = hsLib "template-haskell"
92 terminfo = hsLib "terminfo"
93 text = hsLib "text"
94 time = hsLib "time"
95 touchy = cUtil "touchy"
96 transformers = hsLib "transformers"
97 unlit = cUtil "unlit"
98 unix = hsLib "unix"
99 win32 = hsLib "Win32"
100 xhtml = hsLib "xhtml"
101
102 -- | Construct a Haskell library package, e.g. @array@.
103 hsLib :: PackageName -> Package
104 hsLib name = hsLibrary name ("libraries" -/- name)
105
106 -- | Construct a top-level Haskell library package, e.g. @compiler@.
107 hsTop :: PackageName -> Package
108 hsTop name = hsLibrary name name
109
110 -- | Construct a top-level C library package, e.g. @rts@.
111 cTop :: PackageName -> Package
112 cTop name = cLibrary name name
113
114 -- | Construct a top-level Haskell program package, e.g. @ghc@.
115 hsPrg :: PackageName -> Package
116 hsPrg name = hsProgram name name
117
118 -- | Construct a Haskell utility package, e.g. @haddock@.
119 hsUtil :: PackageName -> Package
120 hsUtil name = hsProgram name ("utils" -/- name)
121
122 -- | Construct a C utility package, e.g. @haddock@.
123 cUtil :: PackageName -> Package
124 cUtil name = cProgram name ("utils" -/- name)
125
126 -- | Amend a package path if it doesn't conform to a typical pattern.
127 setPath :: Package -> FilePath -> Package
128 setPath pkg path = pkg { pkgPath = path }
129
130 -- | Packages that are built by default. You can change this in "UserSettings".
131 defaultPackages :: Stage -> Action [Package]
132 defaultPackages Stage0 = stage0Packages
133 defaultPackages Stage1 = stage1Packages
134 defaultPackages Stage2 = stage2Packages
135 defaultPackages Stage3 = return []
136
137 stage0Packages :: Action [Package]
138 stage0Packages = do
139 win <- windowsHost
140 ios <- iosHost
141 return $ [ binary
142 , cabal
143 , checkApiAnnotations
144 , compareSizes
145 , compiler
146 , deriveConstants
147 , dllSplit
148 , genapply
149 , genprimopcode
150 , ghc
151 , ghcBoot
152 , ghcBootTh
153 , ghcCabal
154 , ghci
155 , ghcPkg
156 , ghcTags
157 , hsc2hs
158 , hp2ps
159 , hpc
160 , mtl
161 , parsec
162 , templateHaskell
163 , text
164 , transformers
165 , unlit ]
166 ++ [ terminfo | not win, not ios ]
167 ++ [ touchy | win ]
168
169 stage1Packages :: Action [Package]
170 stage1Packages = do
171 win <- windowsHost
172 doc <- cmdBuildHaddock
173 intSimple <- cmdIntegerSimple
174 libraries0 <- filter isLibrary <$> stage0Packages
175 return $ libraries0 -- Build all Stage0 libraries in Stage1
176 ++ [ array
177 , base
178 , bytestring
179 , containers
180 , deepseq
181 , directory
182 , filepath
183 , ghc
184 , ghcCabal
185 , ghcCompact
186 , ghcPrim
187 , haskeline
188 , hpcBin
189 , hsc2hs
190 , if intSimple then integerSimple else integerGmp
191 , pretty
192 , process
193 , rts
194 , runGhc
195 , time ]
196 ++ [ iservBin | not win ]
197 ++ [ unix | not win ]
198 ++ [ win32 | win ]
199 ++ [ xhtml | doc ]
200
201 stage2Packages :: Action [Package]
202 stage2Packages = do
203 doc <- cmdBuildHaddock
204 return [ haddock | doc ]
205
206 -- | Given a 'Context', compute the name of the program that is built in it
207 -- assuming that the corresponding package's type is 'Program'. For example, GHC
208 -- built in 'Stage0' is called @ghc-stage1@. If the given package is a
209 -- 'Library', the function simply returns its name.
210 programName :: Context -> String
211 programName Context {..}
212 | package == ghc = "ghc-stage" ++ show (fromEnum stage + 1)
213 | package == hpcBin = "hpc"
214 | package == runGhc = "runhaskell"
215 | package == iservBin = "ghc-iserv"
216 | otherwise = pkgName package
217
218 -- | The build stage whose results are used when installing a package, or
219 -- @Nothing@ if the package is not installed, e.g. because it is a user package.
220 -- The current implementation installs the /latest/ build stage of a package.
221 installStage :: Package -> Action (Maybe Stage)
222 installStage pkg
223 | not (isGhcPackage pkg) = return Nothing -- Only GHC packages are installed
224 | otherwise = do
225 stages <- filterM (fmap (pkg `elem`) . defaultPackages) [Stage0 ..]
226 return $ if null stages then Nothing else Just (maximum stages)
227
228 -- | Is the program corresponding to a given context built 'inplace', i.e. in
229 -- the @inplace/bin@ directory? For most programs, only their /latest/ build
230 -- stages are built 'inplace'. The only exception is the GHC itself, which is
231 -- built 'inplace' in all stages. The function returns @False@ for libraries and
232 -- all user packages.
233 isBuiltInplace :: Context -> Action Bool
234 isBuiltInplace Context {..}
235 | isLibrary package = return False
236 | not (isGhcPackage package) = return False
237 | package == ghc = return True
238 | otherwise = (Just stage ==) <$> installStage package
239
240 -- | The 'FilePath' to a program executable in a given 'Context'.
241 programPath :: Context -> Action FilePath
242 programPath context@Context {..} = do
243 path <- buildPath context
244 inplace <- isBuiltInplace context
245 let contextPath = if inplace then inplacePath else path
246 return $ contextPath -/- programName context <.> exe
247 where
248 inplacePath | package `elem` [touchy, unlit, iservBin] = inplaceLibBinPath
249 | otherwise = inplaceBinPath
250
251 -- | Some contexts are special: their packages do not have @.cabal@ metadata or
252 -- we cannot run @ghc-cabal@ on them, e.g. because the latter hasn't been built
253 -- yet (this is the case with the 'ghcCabal' package in 'Stage0').
254 nonCabalContext :: Context -> Bool
255 nonCabalContext Context {..} = (package `elem` [hp2ps, rts, touchy, unlit])
256 || package == ghcCabal && stage == Stage0
257
258 -- | Some program packages should not be linked with Haskell main function.
259 nonHsMainPackage :: Package -> Bool
260 nonHsMainPackage = (`elem` [ghc, hp2ps, iservBin, touchy, unlit])
261
262 -- | Path to the autogen directory generated by @ghc-cabal@ of a given 'Context'.
263 autogenPath :: Context -> Action FilePath
264 autogenPath context@Context {..}
265 | isLibrary package = autogen "build"
266 | package == ghc = autogen "build/ghc"
267 | package == hpcBin = autogen "build/hpc"
268 | package == iservBin = autogen "build/iserv"
269 | otherwise = autogen $ "build" -/- pkgName package
270 where
271 autogen dir = buildPath context <&> (-/- dir -/- "autogen")
272
273 -- | @ghc-split@ is a Perl script used by GHC with @-split-objs@ flag. It is
274 -- generated in "Rules.Generators.GhcSplit".
275 ghcSplitPath :: FilePath
276 ghcSplitPath = inplaceLibBinPath -/- "ghc-split"
277
278 -- ref: mk/config.mk
279 -- | Command line tool for stripping.
280 stripCmdPath :: Action FilePath
281 stripCmdPath = do
282 targetPlatform <- setting TargetPlatform
283 top <- topDirectory
284 case targetPlatform of
285 "x86_64-unknown-mingw32" ->
286 return (top -/- "inplace/mingw/bin/strip.exe")
287 "arm-unknown-linux" ->
288 return ":" -- HACK: from the make-based system, see the ref above
289 _ -> return "strip"
290
291 buildDll0 :: Context -> Action Bool
292 buildDll0 Context {..} = do
293 windows <- windowsHost
294 return $ windows && stage == Stage1 && package == compiler