Use Cabal directly in place of ghc-cabal + make build root configurable (#531)
[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, 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 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 , ghci
50 , ghcPkg
51 , ghcTags
52 , hsc2hs
53 , hp2ps
54 , hpc
55 , mtl
56 , parsec
57 , templateHaskell
58 , text
59 , transformers
60 , unlit ]
61 ++ [ terminfo | not win, not cross ]
62 ++ [ touchy | win ]
63
64 stage1Packages :: Action [Package]
65 stage1Packages = do
66 win <- windowsHost
67 intLib <- integerLibrary =<< flavour
68 libraries0 <- filter isLibrary <$> stage0Packages
69 cross <- crossCompiling
70 return $ libraries0 -- Build all Stage0 libraries in Stage1
71 ++ [ array
72 , base
73 , bytestring
74 , containers
75 , deepseq
76 , directory
77 , filepath
78 , ghc
79 , ghcCompact
80 , ghcPkg
81 , ghcPrim
82 , haskeline
83 , hsc2hs
84 , intLib
85 , pretty
86 , process
87 , rts
88 , stm
89 , time
90 , unlit
91 , xhtml ]
92 ++ [ haddock | not cross ]
93 ++ [ runGhc | not cross ]
94 ++ [ hpcBin | not cross ]
95 ++ [ iservBin | not win, not cross ]
96 ++ [ unix | not win ]
97 ++ [ win32 | win ]
98
99 stage2Packages :: Action [Package]
100 stage2Packages = return [haddock]
101
102 -- | Given a 'Context', compute the name of the program that is built in it
103 -- assuming that the corresponding package's type is 'Program'. For example, GHC
104 -- built in 'Stage0' is called @ghc-stage1@. If the given package is a
105 -- 'Library', the function simply returns its name.
106 programName :: Context -> Action String
107 programName Context {..} = do
108 cross <- crossCompiling
109 targetPlatform <- setting TargetPlatformFull
110 let prefix = if cross then targetPlatform ++ "-" else ""
111 in return $ prefix ++ case package of
112 p | p == ghc -> "ghc"
113 | p == hpcBin -> "hpc"
114 | p == runGhc -> "runhaskell"
115 | p == iservBin -> "ghc-iserv"
116 _ -> pkgName package
117
118 -- | The build stage whose results are used when installing a package, or
119 -- @Nothing@ if the package is not installed, e.g. because it is a user package.
120 -- The current implementation installs the /latest/ build stage of a package.
121 installStage :: Package -> Action (Maybe Stage)
122 installStage pkg
123 | not (isGhcPackage pkg) = return Nothing -- Only GHC packages are installed
124 | otherwise = do
125 stages <- filterM (fmap (pkg `elem`) . defaultPackages) [Stage0 ..]
126 return $ if null stages then Nothing else Just (maximum stages)
127
128 -- | The 'FilePath' to a program executable in a given 'Context'.
129 programPath :: Context -> Action FilePath
130 programPath context@Context {..} = do
131 path <- stageBinPath stage
132 pgm <- programName context
133 return $ path -/- pgm <.> exe
134
135 -- | Some contexts are special: their packages do not have @.cabal@ metadata or
136 -- we cannot run @ghc-cabal@ on them, e.g. because the latter hasn't been built
137 -- yet (this is the case with the 'ghcCabal' package in 'Stage0').
138 nonCabalContext :: Context -> Bool
139 nonCabalContext Context {..} = (package `elem` [ hp2ps
140 , touchy
141 ])
142 || package == ghcCabal && stage == Stage0
143
144 -- | Some program packages should not be linked with Haskell main function.
145 nonHsMainPackage :: Package -> Bool
146 nonHsMainPackage = (`elem` [ghc, hp2ps, iservBin, touchy, unlit])
147
148 -- | Path to the autogen directory generated by @ghc-cabal@ of a given 'Context'.
149 autogenPath :: Context -> Action FilePath
150 autogenPath context@Context {..}
151 | isLibrary package = autogen "build"
152 | package == ghc = autogen "build/ghc"
153 | package == hpcBin = autogen "build/hpc"
154 | package == iservBin = autogen "build/iserv"
155 | otherwise = autogen $ "build" -/- pkgName package
156 where
157 autogen dir = contextPath context <&> (-/- dir -/- "autogen")
158
159 -- ref: mk/config.mk
160 -- | Command line tool for stripping.
161 stripCmdPath :: Action FilePath
162 stripCmdPath = do
163 targetPlatform <- setting TargetPlatform
164 top <- topDirectory
165 case targetPlatform of
166 "x86_64-unknown-mingw32" ->
167 return (top -/- "inplace/mingw/bin/strip.exe")
168 "arm-unknown-linux" ->
169 return ":" -- HACK: from the make-based system, see the ref above
170 _ -> return "strip"
171
172 buildDll0 :: Context -> Action Bool
173 buildDll0 Context {..} = do
174 windows <- windowsHost
175 return $ windows && stage == Stage1 && package == compiler