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