2a87d68cca1b220594e2ce9f724342746d934292
[hadrian.git] / src / GHC.hs
1 {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
2 module GHC (
3 -- * GHC packages
4 array, base, binary, bytestring, cabal, compareSizes, compiler, containers,
5 deepseq, deriveConstants, directory, filepath, genapply, genprimopcode, ghc,
6 ghcBoot, ghcBootTh, ghcCabal, ghcCompact, ghci, ghcPkg, ghcPrim, ghcTags,
7 ghcSplit, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp,
8 integerSimple, iservBin, iservLib, libffi, mtl, parsec, parallel, pretty,
9 primitive, process, rts, runGhc, stm, templateHaskell, terminfo, text, time,
10 touchy, transformers, unlit, unix, win32, xhtml, ghcPackages, isGhcPackage,
11 defaultPackages,
12
13 -- * Package information
14 programName, nonCabalContext, nonHsMainPackage, autogenPath, installStage,
15
16 -- * Miscellaneous
17 programPath, buildDll0
18 ) where
19
20 import Base
21 import CommandLine
22 import Context
23 import Oracles.Flag
24 import Oracles.Setting
25
26 -- | These are all GHC packages we know about. Build rules will be generated for
27 -- all of them. However, not all of these packages will be built. For example,
28 -- package 'win32' is built only on Windows. 'defaultPackages' defines default
29 -- conditions for building each package. Users can add their own packages and
30 -- modify build default build conditions in "UserSettings".
31 ghcPackages :: [Package]
32 ghcPackages =
33 [ array, base, binary, bytestring, cabal, compareSizes, compiler, containers
34 , deepseq, deriveConstants, directory, filepath, genapply, genprimopcode
35 , ghc, ghcBoot, ghcBootTh, ghcCabal, ghcCompact, ghci, ghcPkg, ghcPrim
36 , ghcTags, haddock, haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp
37 , integerSimple, iservBin, iservLib, libffi, mtl, parsec, parallel, pretty
38 , primitive, process, rts, runGhc, stm, templateHaskell, terminfo, text
39 , time, touchy, transformers, unlit, unix, 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 compareSizes = hsUtil "compareSizes" `setPath` "utils/compare_sizes"
52 compiler = hsTop "ghc" `setPath` "compiler"
53 containers = hsLib "containers"
54 deepseq = hsLib "deepseq"
55 deriveConstants = hsUtil "deriveConstants"
56 directory = hsLib "directory"
57 filepath = hsLib "filepath"
58 genapply = hsUtil "genapply"
59 genprimopcode = hsUtil "genprimopcode"
60 ghc = hsPrg "ghc-bin" `setPath` "ghc"
61 ghcBoot = hsLib "ghc-boot"
62 ghcBootTh = hsLib "ghc-boot-th"
63 ghcCabal = hsUtil "ghc-cabal"
64 ghcCompact = hsLib "ghc-compact"
65 ghci = hsLib "ghci"
66 ghcPkg = hsUtil "ghc-pkg"
67 ghcPrim = hsLib "ghc-prim"
68 ghcTags = hsUtil "ghctags"
69 ghcSplit = hsUtil "ghc-split"
70 haddock = hsUtil "haddock"
71 haskeline = hsLib "haskeline"
72 hsc2hs = hsUtil "hsc2hs"
73 hp2ps = cUtil "hp2ps"
74 hpc = hsLib "hpc"
75 hpcBin = hsUtil "hpc-bin" `setPath` "utils/hpc"
76 integerGmp = hsLib "integer-gmp"
77 integerSimple = hsLib "integer-simple"
78 -- iservBin = hsUtil "iserv" -- FIXME: See #507
79 iservBin = hsPrg "iserv-bin" `setPath` "iserv"
80 iservLib = hsLib "libiserv"
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 cross <- crossCompiling
142 return $ [ binary
143 , cabal
144 , compareSizes
145 , compiler
146 , deriveConstants
147 , genapply
148 , genprimopcode
149 , ghc
150 , ghcBoot
151 , ghcBootTh
152 , ghcCabal
153 , ghci
154 , ghcPkg
155 , ghcTags
156 , hsc2hs
157 , hp2ps
158 , hpc
159 , mtl
160 , parsec
161 , templateHaskell
162 , text
163 , transformers
164 , unlit ]
165 ++ [ terminfo | not win, not ios, not cross ]
166 ++ [ touchy | win ]
167
168 stage1Packages :: Action [Package]
169 stage1Packages = do
170 win <- windowsHost
171 intSimple <- cmdIntegerSimple
172 libraries0 <- filter isLibrary <$> stage0Packages
173 return $ libraries0 -- Build all Stage0 libraries in Stage1
174 ++ [ array
175 , base
176 , bytestring
177 , containers
178 , deepseq
179 , directory
180 , filepath
181 , ghc
182 , ghcCabal
183 , ghcCompact
184 , ghcPrim
185 , haskeline
186 , hpcBin
187 , hsc2hs
188 , if intSimple then integerSimple else integerGmp
189 , pretty
190 , process
191 , rts
192 , runGhc
193 , stm
194 , time
195 , xhtml ]
196 ++ [ iservBin | not win ]
197 -- ++ [ iservLib | not win ] -- FIXME: See #507
198 ++ [ unix | not win ]
199 ++ [ win32 | win ]
200
201 stage2Packages :: Action [Package]
202 stage2Packages = return [haddock]
203
204 -- | Given a 'Context', compute the name of the program that is built in it
205 -- assuming that the corresponding package's type is 'Program'. For example, GHC
206 -- built in 'Stage0' is called @ghc-stage1@. If the given package is a
207 -- 'Library', the function simply returns its name.
208 programName :: Context -> String
209 programName Context {..}
210 | package == ghc = "ghc-stage" ++ show (fromEnum stage + 1)
211 | package == hpcBin = "hpc"
212 | package == runGhc = "runhaskell"
213 | package == iservBin = "ghc-iserv"
214 | otherwise = pkgName package
215
216 -- | The build stage whose results are used when installing a package, or
217 -- @Nothing@ if the package is not installed, e.g. because it is a user package.
218 -- The current implementation installs the /latest/ build stage of a package.
219 installStage :: Package -> Action (Maybe Stage)
220 installStage pkg
221 | not (isGhcPackage pkg) = return Nothing -- Only GHC packages are installed
222 | otherwise = do
223 stages <- filterM (fmap (pkg `elem`) . defaultPackages) [Stage0 ..]
224 return $ if null stages then Nothing else Just (maximum stages)
225
226 -- | Is the program corresponding to a given context built 'inplace', i.e. in
227 -- the @inplace/bin@ directory? For most programs, only their /latest/ build
228 -- stages are built 'inplace'. The only exception is the GHC itself, which is
229 -- built 'inplace' in all stages. The function returns @False@ for libraries and
230 -- all user packages.
231 isBuiltInplace :: Context -> Action Bool
232 isBuiltInplace Context {..}
233 | isLibrary package = return False
234 | not (isGhcPackage package) = return False
235 | package == ghc = return True
236 | otherwise = (Just stage ==) <$> installStage package
237
238 -- | The 'FilePath' to a program executable in a given 'Context'.
239 programPath :: Context -> Action FilePath
240 programPath context@Context {..} = do
241 path <- buildPath context
242 inplace <- isBuiltInplace context
243 let contextPath = if inplace then inplacePath else path
244 return $ contextPath -/- programName context <.> exe
245 where
246 inplacePath | package `elem` [touchy, unlit, iservBin] = inplaceLibBinPath
247 | otherwise = inplaceBinPath
248
249 -- | Some contexts are special: their packages do not have @.cabal@ metadata or
250 -- we cannot run @ghc-cabal@ on them, e.g. because the latter hasn't been built
251 -- yet (this is the case with the 'ghcCabal' package in 'Stage0').
252 nonCabalContext :: Context -> Bool
253 nonCabalContext Context {..} = (package `elem` [hp2ps, rts, touchy, unlit])
254 || package == ghcCabal && stage == Stage0
255
256 -- | Some program packages should not be linked with Haskell main function.
257 nonHsMainPackage :: Package -> Bool
258 nonHsMainPackage = (`elem` [ghc, hp2ps, iservBin, touchy, unlit])
259
260 -- | Path to the autogen directory generated by @ghc-cabal@ of a given 'Context'.
261 autogenPath :: Context -> Action FilePath
262 autogenPath context@Context {..}
263 | isLibrary package = autogen "build"
264 | package == ghc = autogen "build/ghc"
265 | package == hpcBin = autogen "build/hpc"
266 | package == iservBin = autogen "build/iserv"
267 | otherwise = autogen $ "build" -/- pkgName package
268 where
269 autogen dir = buildPath context <&> (-/- dir -/- "autogen")
270
271 buildDll0 :: Context -> Action Bool
272 buildDll0 Context {..} = do
273 windows <- windowsHost
274 return $ windows && stage == Stage1 && package == compiler