b3002b894442e073e986f29af136fe5569a1adcc
[ghc.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, ghcCompact,
7 ghcHeap, ghci, ghcPkg, ghcPrim, ghcTags, ghcSplit, haddock, haskeline,
8 hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi,
9 libiserv, mtl, parsec, parallel, pretty, primitive, process, rts, runGhc,
10 stm, templateHaskell, terminfo, text, time, touchy, transformers, unlit,
11 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 = do
109 win <- windowsHost
110 return $
111 [ checkApiAnnotations
112 , checkPpr
113 , ghci
114 , ghcPkg
115 , hp2ps
116 , iserv
117 , parallel
118 , runGhc ] ++
119 [ timeout | win ]
120
121 -- | Given a 'Context', compute the name of the program that is built in it
122 -- assuming that the corresponding package's type is 'Program'. For example, GHC
123 -- built in 'Stage0' is called @ghc-stage1@. If the given package is a
124 -- 'Library', the function simply returns its name.
125 programName :: Context -> Action String
126 programName Context {..} = do
127 cross <- flag CrossCompiling
128 targetPlatform <- setting TargetPlatformFull
129 let prefix = if cross then targetPlatform ++ "-" else ""
130 in return $ prefix ++ case package of
131 p | p == ghc -> "ghc"
132 | p == hpcBin -> "hpc"
133 | p == runGhc -> "runhaskell"
134 | p == iserv -> "ghc-iserv"
135 _ -> pkgName package
136
137 -- | The build stage whose results are used when installing a package, or
138 -- @Nothing@ if the package is not installed, e.g. because it is a user package.
139 -- The current implementation installs the /latest/ build stage of a package.
140 installStage :: Package -> Action (Maybe Stage)
141 installStage pkg
142 | not (isGhcPackage pkg) = return Nothing -- Only GHC packages are installed
143 | otherwise = do
144 stages <- filterM (fmap (pkg `elem`) . defaultPackages) [Stage0 ..]
145 return $ if null stages then Nothing else Just (maximum stages)
146
147 -- | The 'FilePath' to a program executable in a given 'Context'.
148 programPath :: Context -> Action FilePath
149 programPath context@Context {..} = do
150 -- The @touchy@ utility lives in the @lib/bin@ directory instead of @bin@,
151 -- which is likely just a historical accident that will hopefully be fixed.
152 -- See: https://github.com/snowleopard/hadrian/issues/570
153 -- Likewise for 'unlit'.
154 path <- if package `elem` [touchy, unlit]
155 then stageLibPath stage <&> (-/- "bin")
156 else stageBinPath stage
157 pgm <- programName context
158 return $ path -/- pgm <.> exe
159
160 -- TODO: This is no longer true -- both @hp2ps@ and @touchy@ appear to have been
161 -- Cabal-ised, so we need to drop these special cases.
162 -- | Some contexts are special: their packages do not have @.cabal@ metadata.
163 nonCabalContext :: Context -> Bool
164 nonCabalContext Context {..} = (package `elem` [hp2ps, touchy])
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 when configuring a package.
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"