9b453e58d7c57d35bd77393fc34565972d0fbfe6
[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, checkPpr,
5 compareSizes, compiler, containers, deepseq, deriveConstants, directory,
6 filepath, genapply, genprimopcode, ghc, ghcBoot, ghcBootTh, ghcCabal,
7 ghcCompact, ghcHeap, ghci, ghcPkg, ghcPrim, ghcTags, ghcSplit, haddock,
8 haskeline, hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv,
9 libffi, libiserv, mtl, parsec, parallel, pretty, primitive, process, rts,
10 runGhc, stm, templateHaskell, terminfo, text, time, touchy, transformers,
11 unlit, unix, win32, xhtml, ghcPackages, isGhcPackage, defaultPackages,
12 testsuitePackages,
13
14 -- * Package information
15 programName, nonCabalContext, nonHsMainPackage, autogenPath, installStage,
16
17 -- * Miscellaneous
18 programPath, buildDll0, rtsContext, rtsBuildPath, libffiContext,
19 libffiBuildPath, libffiLibraryName
20 ) where
21
22 import Base
23 import Context
24 import Flavour
25 import GHC.Packages
26 import Oracles.Flag
27 import Oracles.Setting
28 import Settings (flavour)
29
30 -- | Packages that are built by default. You can change this in "UserSettings".
31 defaultPackages :: Stage -> Action [Package]
32 defaultPackages Stage0 = stage0Packages
33 defaultPackages Stage1 = stage1Packages
34 defaultPackages Stage2 = stage2Packages
35 defaultPackages Stage3 = return []
36
37 stage0Packages :: Action [Package]
38 stage0Packages = do
39 win <- windowsHost
40 cross <- flag CrossCompiling
41 return $ [ binary
42 , cabal
43 , compareSizes
44 , compiler
45 , deriveConstants
46 , genapply
47 , genprimopcode
48 , ghc
49 , ghcBoot
50 , ghcBootTh
51 , ghcHeap
52 , ghci
53 , ghcPkg
54 , ghcTags
55 , hsc2hs
56 , hp2ps
57 , hpc
58 , mtl
59 , parsec
60 , templateHaskell
61 , text
62 , transformers
63 , unlit ]
64 ++ [ terminfo | not win, not cross ]
65 ++ [ touchy | win ]
66
67 stage1Packages :: Action [Package]
68 stage1Packages = do
69 win <- windowsHost
70 intLib <- integerLibrary =<< flavour
71 libraries0 <- filter isLibrary <$> stage0Packages
72 cross <- flag CrossCompiling
73 return $ libraries0 -- Build all Stage0 libraries in Stage1
74 ++ [ array
75 , base
76 , bytestring
77 , containers
78 , deepseq
79 , directory
80 , filepath
81 , ghc
82 , ghcCompact
83 , ghcPkg
84 , ghcPrim
85 , haskeline
86 , hsc2hs
87 , intLib
88 , pretty
89 , process
90 , rts
91 , stm
92 , time
93 , unlit
94 , xhtml ]
95 ++ [ haddock | not cross ]
96 ++ [ runGhc | not cross ]
97 ++ [ hpcBin | not cross ]
98 ++ [ iserv | not win, not cross ]
99 ++ [ libiserv | not win, not cross ]
100 ++ [ unix | not win ]
101 ++ [ win32 | win ]
102
103 stage2Packages :: Action [Package]
104 stage2Packages = return [haddock]
105
106 -- | Packages that are built only for the testsuite.
107 testsuitePackages :: Action [Package]
108 testsuitePackages = return [ checkApiAnnotations
109 , checkPpr
110 , ghci
111 , ghcPkg
112 , hp2ps
113 , iserv
114 , parallel
115 , runGhc
116 , timeout ]
117
118 -- | Given a 'Context', compute the name of the program that is built in it
119 -- assuming that the corresponding package's type is 'Program'. For example, GHC
120 -- built in 'Stage0' is called @ghc-stage1@. If the given package is a
121 -- 'Library', the function simply returns its name.
122 programName :: Context -> Action String
123 programName Context {..} = do
124 cross <- flag CrossCompiling
125 targetPlatform <- setting TargetPlatformFull
126 let prefix = if cross then targetPlatform ++ "-" else ""
127 in return $ prefix ++ case package of
128 p | p == ghc -> "ghc"
129 | p == hpcBin -> "hpc"
130 | p == runGhc -> "runhaskell"
131 | p == iserv -> "ghc-iserv"
132 _ -> pkgName package
133
134 -- | The build stage whose results are used when installing a package, or
135 -- @Nothing@ if the package is not installed, e.g. because it is a user package.
136 -- The current implementation installs the /latest/ build stage of a package.
137 installStage :: Package -> Action (Maybe Stage)
138 installStage pkg
139 | not (isGhcPackage pkg) = return Nothing -- Only GHC packages are installed
140 | otherwise = do
141 stages <- filterM (fmap (pkg `elem`) . defaultPackages) [Stage0 ..]
142 return $ if null stages then Nothing else Just (maximum stages)
143
144 -- | The 'FilePath' to a program executable in a given 'Context'.
145 programPath :: Context -> Action FilePath
146 programPath context@Context {..} = do
147 -- The @touchy@ utility lives in the @lib/bin@ directory instead of @bin@,
148 -- which is likely just a historical accident that will hopefully be fixed.
149 -- See: https://github.com/snowleopard/hadrian/issues/570
150 -- Likewise for 'unlit'.
151 path <- if package `elem` [touchy, unlit]
152 then stageLibPath stage <&> (-/- "bin")
153 else stageBinPath stage
154 pgm <- programName context
155 return $ path -/- pgm <.> exe
156
157 -- | Some contexts are special: their packages do not have @.cabal@ metadata or
158 -- we cannot run @ghc-cabal@ on them, e.g. because the latter hasn't been built
159 -- yet (this is the case with the 'ghcCabal' package in 'Stage0').
160 nonCabalContext :: Context -> Bool
161 nonCabalContext Context {..} = (package `elem` [ hp2ps
162 , touchy
163 ])
164 || package == ghcCabal && stage == Stage0
165
166 -- | Some program packages should not be linked with Haskell main function.
167 nonHsMainPackage :: Package -> Bool
168 nonHsMainPackage = (`elem` [ghc, hp2ps, iserv, touchy, unlit])
169
170 -- | Path to the autogen directory generated by @ghc-cabal@ of a given 'Context'.
171 autogenPath :: Context -> Action FilePath
172 autogenPath context@Context {..}
173 | isLibrary package = autogen "build"
174 | package == ghc = autogen "build/ghc"
175 | package == hpcBin = autogen "build/hpc"
176 | otherwise = autogen $ "build" -/- pkgName package
177 where
178 autogen dir = contextPath context <&> (-/- dir -/- "autogen")
179
180 buildDll0 :: Context -> Action Bool
181 buildDll0 Context {..} = do
182 windows <- windowsHost
183 return $ windows && stage == Stage1 && package == compiler
184
185 -- | RTS is considered a Stage1 package. This determines RTS build directory.
186 rtsContext :: Context
187 rtsContext = vanillaContext Stage1 rts
188
189 -- | Path to the RTS build directory.
190 rtsBuildPath :: Action FilePath
191 rtsBuildPath = buildPath rtsContext
192
193 -- | Libffi is considered a Stage1 package. This determines its build directory.
194 libffiContext :: Context
195 libffiContext = vanillaContext Stage1 libffi
196
197 -- | Build directory for in-tree Libffi library.
198 libffiBuildPath :: Action FilePath
199 libffiBuildPath = buildPath libffiContext
200
201 libffiLibraryName :: Action FilePath
202 libffiLibraryName = do
203 useSystemFfi <- flag UseSystemFfi
204 windows <- windowsHost
205 return $ case (useSystemFfi, windows) of
206 (True , False) -> "ffi"
207 (False, False) -> "Cffi"
208 (_ , True ) -> "Cffi-6"