8d2aef1c7bc1b7c2da4d385a1f104d2228f1d455
[ghc.git] / hadrian / src / Packages.hs
1 {-# OPTIONS_GHC -fno-warn-missing-signatures #-}
2 module Packages (
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, ghcSplit, haddock, haskeline,
8 hsc2hs, hp2ps, hpc, hpcBin, integerGmp, integerSimple, iserv, libffi,
9 libiserv, mtl, parsec, pretty, primitive, process, rts, runGhc,
10 stm, templateHaskell, terminfo, text, time, timeout, touchy, transformers,
11 unlit, unix, win32, xhtml, ghcPackages, isGhcPackage,
12
13 -- * Package information
14 programName, nonHsMainPackage, autogenPath, programPath, timeoutPath,
15 rtsContext, rtsBuildPath, libffiContext, libffiBuildPath, libffiLibraryName,
16 generatedGhcDependencies, ensureConfigured
17 ) where
18
19 import Hadrian.Package
20 import Hadrian.Utilities
21
22 import Base
23 import Context
24 import Oracles.Flag
25 import Oracles.Setting
26
27 -- | These are all GHC packages we know about. Build rules will be generated for
28 -- all of them. However, not all of these packages will be built. For example,
29 -- package 'win32' is built only on Windows. @GHC.defaultPackages@ defines
30 -- default conditions for building each package. Users can add their own
31 -- packages and modify build default build conditions in "UserSettings".
32 ghcPackages :: [Package]
33 ghcPackages =
34 [ array, base, binary, bytestring, cabal, checkPpr, checkApiAnnotations
35 , compareSizes, compiler, containers, deepseq, deriveConstants, directory
36 , filepath, genapply, genprimopcode, ghc, ghcBoot, ghcBootTh, ghcCompact
37 , ghcHeap, ghci, ghcPkg, ghcPrim, haddock, haskeline, hsc2hs, hp2ps
38 , hpc, hpcBin, integerGmp, integerSimple, iserv, libffi, libiserv, mtl
39 , parsec, pretty, process, rts, runGhc, stm, templateHaskell
40 , terminfo, text, time, touchy, transformers, unlit, unix, win32, xhtml
41 , timeout ]
42
43 -- TODO: Optimise by switching to sets of packages.
44 isGhcPackage :: Package -> Bool
45 isGhcPackage = (`elem` ghcPackages)
46
47 -- | Package definitions, see 'Package'.
48 array = lib "array"
49 base = lib "base"
50 binary = lib "binary"
51 bytestring = lib "bytestring"
52 cabal = lib "Cabal" `setPath` "libraries/Cabal/Cabal"
53 checkApiAnnotations = util "check-api-annotations"
54 checkPpr = util "check-ppr"
55 compareSizes = util "compareSizes" `setPath` "utils/compare_sizes"
56 compiler = top "ghc" `setPath` "compiler"
57 containers = lib "containers"
58 deepseq = lib "deepseq"
59 deriveConstants = util "deriveConstants"
60 directory = lib "directory"
61 filepath = lib "filepath"
62 genapply = util "genapply"
63 genprimopcode = util "genprimopcode"
64 ghc = prg "ghc-bin" `setPath` "ghc"
65 ghcBoot = lib "ghc-boot"
66 ghcBootTh = lib "ghc-boot-th"
67 ghcCompact = lib "ghc-compact"
68 ghcHeap = lib "ghc-heap"
69 ghci = lib "ghci"
70 ghcPkg = util "ghc-pkg"
71 ghcPrim = lib "ghc-prim"
72 ghcSplit = util "ghc-split"
73 haddock = util "haddock"
74 haskeline = lib "haskeline"
75 hsc2hs = util "hsc2hs"
76 hp2ps = util "hp2ps"
77 hpc = lib "hpc"
78 hpcBin = util "hpc-bin" `setPath` "utils/hpc"
79 integerGmp = lib "integer-gmp"
80 integerSimple = lib "integer-simple"
81 iserv = util "iserv"
82 libffi = top "libffi"
83 libiserv = lib "libiserv"
84 mtl = lib "mtl"
85 parsec = lib "parsec"
86 pretty = lib "pretty"
87 primitive = lib "primitive"
88 process = lib "process"
89 rts = top "rts"
90 runGhc = util "runghc"
91 stm = lib "stm"
92 templateHaskell = lib "template-haskell"
93 terminfo = lib "terminfo"
94 text = lib "text"
95 time = lib "time"
96 timeout = util "timeout" `setPath` "testsuite/timeout"
97 touchy = util "touchy"
98 transformers = lib "transformers"
99 unlit = util "unlit"
100 unix = lib "unix"
101 win32 = lib "Win32"
102 xhtml = lib "xhtml"
103
104 -- | Construct a library package, e.g. @array@.
105 lib :: PackageName -> Package
106 lib name = library name ("libraries" -/- name)
107
108 -- | Construct a top-level library package, e.g. @compiler@.
109 top :: PackageName -> Package
110 top name = library name name
111
112 -- | Construct a top-level program package, e.g. @ghc@.
113 prg :: PackageName -> Package
114 prg name = program name name
115
116 -- | Construct a utility package, e.g. @haddock@.
117 util :: PackageName -> Package
118 util name = program name ("utils" -/- name)
119
120 -- | Amend a package path if it doesn't conform to a typical pattern.
121 setPath :: Package -> FilePath -> Package
122 setPath pkg path = pkg { pkgPath = path }
123
124 -- | Given a 'Context', compute the name of the program that is built in it
125 -- assuming that the corresponding package's type is 'Program'. For example, GHC
126 -- built in 'Stage0' is called @ghc-stage1@. If the given package is a
127 -- 'Library', the function simply returns its name.
128 programName :: Context -> Action String
129 programName Context {..} = do
130 cross <- flag CrossCompiling
131 targetPlatform <- setting TargetPlatformFull
132 let prefix = if cross then targetPlatform ++ "-" else ""
133 -- TODO: Can we extract this information from Cabal files?
134 -- Alp: We could, but then the iserv package would have to
135 -- use Cabal conditionals + a 'profiling' flag
136 -- to declare the executable name, and I'm not sure
137 -- this is allowed (or desired for that matter).
138 return $ prefix ++ case package of
139 p | p == ghc -> "ghc"
140 | p == hpcBin -> "hpc"
141 | p == iserv -> "ghc-iserv" ++ concat [
142 if wayUnit' `wayUnit` way
143 then suffix
144 else ""
145 | (wayUnit', suffix) <- [
146 (Profiling, "-prof"),
147 (Dynamic, "-dyn")
148 ]]
149 _ -> pkgName package
150
151 -- | The 'FilePath' to a program executable in a given 'Context'.
152 programPath :: Context -> Action FilePath
153 programPath context@Context {..} = do
154 -- TODO: The @touchy@ utility lives in the @lib/bin@ directory instead of
155 -- @bin@, which is likely just a historical accident that should be fixed.
156 -- See: https://github.com/snowleopard/hadrian/issues/570
157 -- Likewise for @iserv@ and @unlit@.
158 name <- programName context
159 path <- if package `elem` [iserv, touchy, unlit]
160 then stageLibPath stage <&> (-/- "bin")
161 else stageBinPath stage
162 return $ path -/- name <.> exe
163
164 -- TODO: Move @timeout@ to the @util@ directory and build in a more standard
165 -- location like other programs used only by the testsuite.
166 timeoutPath :: FilePath
167 timeoutPath = "testsuite/timeout/install-inplace/bin/timeout" <.> exe
168
169 -- TODO: Can we extract this information from Cabal files?
170 -- | Some program packages should not be linked with Haskell main function.
171 nonHsMainPackage :: Package -> Bool
172 nonHsMainPackage = (`elem` [ghc, hp2ps, iserv, touchy, unlit])
173
174 -- TODO: Combine this with 'programName'.
175 -- | Path to the @autogen@ directory generated by 'buildAutogenFiles'.
176 autogenPath :: Context -> Action FilePath
177 autogenPath context@Context {..}
178 | isLibrary package = autogen "build"
179 | package == ghc = autogen "build/ghc"
180 | package == hpcBin = autogen "build/hpc"
181 | otherwise = autogen $ "build" -/- pkgName package
182 where
183 autogen dir = contextPath context <&> (-/- dir -/- "autogen")
184
185 -- | Make sure a given context has already been fully configured. The
186 -- implementation simply calls 'need' on the context's @autogen/cabal_macros.h@
187 -- file, which triggers 'configurePackage' and 'buildAutogenFiles'. Why this
188 -- indirection? Going via @autogen/cabal_macros.h@ allows us to cache the
189 -- configuration steps, i.e. not to repeat them if they have already been done.
190 ensureConfigured :: Context -> Action ()
191 ensureConfigured context = do
192 autogen <- autogenPath context
193 need [autogen -/- "cabal_macros.h"]
194
195 -- | RTS is considered a Stage1 package. This determines RTS build directory.
196 rtsContext :: Stage -> Context
197 rtsContext stage = vanillaContext stage rts
198
199 -- | Path to the RTS build directory.
200 rtsBuildPath :: Stage -> Action FilePath
201 rtsBuildPath stage = buildPath (rtsContext stage)
202
203 -- | Build directory for @libffi@. This probably doesn't need to be stage
204 -- dependent but it is for consistency for now.
205 libffiContext :: Stage -> Context
206 libffiContext stage = vanillaContext stage libffi
207
208 -- | Build directory for in-tree 'libffi' library.
209 libffiBuildPath :: Stage -> Action FilePath
210 libffiBuildPath stage = buildPath (libffiContext stage)
211
212 -- | Name of the 'libffi' library.
213 libffiLibraryName :: Action FilePath
214 libffiLibraryName = do
215 useSystemFfi <- flag UseSystemFfi
216 windows <- windowsHost
217 return $ case (useSystemFfi, windows) of
218 (True , False) -> "ffi"
219 (False, False) -> "Cffi"
220 (_ , True ) -> "Cffi-6"
221
222 -- | Generated header files required by GHC in runtime.
223 generatedGhcDependencies :: Stage -> Action [FilePath]
224 generatedGhcDependencies stage = do
225 let context = vanillaContext stage compiler
226 bh <- buildPath context <&> (-/- "ghc_boot_platform.h")
227 ch <- contextPath context <&> (-/- "ghc_boot_platform.h")
228 is <- includesDependencies
229 return $ is ++ [bh, ch]