Moves wordsWhen into Base, and adjusts names and types to be more descriptive.
[hadrian.git] / src / Builder.hs
1 {-# LANGUAGE DeriveGeneric #-}
2 module Builder (
3 Builder (..), isStaged, builderPath, getBuilderPath, specified, needBuilder
4 ) where
5
6 import Control.Monad.Trans.Reader
7
8 import Base
9 import GHC.Generics (Generic)
10 import Oracles
11 import Stage
12
13 -- | A 'Builder' is an external command invoked in separate process using 'Shake.cmd'
14 --
15 -- @Ghc Stage0@ is the bootstrapping compiler
16 -- @Ghc StageN@, N > 0, is the one built on stage (N - 1)
17 -- @GhcPkg Stage0@ is the bootstrapping @GhcPkg@
18 -- @GhcPkg StageN@, N > 0, is the one built in Stage0 (TODO: need only Stage1?)
19 -- TODO: Do we really need HsCpp builder? Can't we use a generic Cpp
20 -- builder instead? It would also be used instead of GccM.
21 -- TODO: rename Gcc to CCompiler? We sometimes use gcc and sometimes clang.
22 -- TODO: why are Gcc/GccM staged?
23 data Builder = Alex
24 | Ar
25 | DeriveConstants
26 | Gcc Stage
27 | GccM Stage
28 | GenApply
29 | GenPrimopCode
30 | Ghc Stage
31 | GhcCabal
32 | GhcCabalHsColour
33 | GhcM Stage
34 | GhcPkg Stage
35 | GhcSplit
36 | Haddock
37 | Happy
38 | HsColour
39 | HsCpp
40 | Hsc2Hs
41 | Ld
42 | Nm
43 | Objdump
44 | Ranlib
45 | Tar
46 | Unlit
47 deriving (Show, Eq, Generic)
48
49 isStaged :: Builder -> Bool
50 isStaged (Gcc _) = True
51 isStaged (GccM _) = True
52 isStaged (Ghc _) = True
53 isStaged (GhcM _) = True
54 isStaged (GhcPkg _) = True
55 isStaged _ = False
56
57 -- Configuration files refer to Builders as follows:
58 builderKey :: Builder -> String
59 builderKey builder = case builder of
60 Alex -> "alex"
61 Ar -> "ar"
62 DeriveConstants -> "derive-constants"
63 Gcc Stage0 -> "system-gcc"
64 Gcc _ -> "gcc"
65 GccM stage -> builderKey $ Gcc stage -- synonym for 'Gcc -MM'
66 GenApply -> "genapply"
67 GenPrimopCode -> "genprimopcode"
68 Ghc Stage0 -> "system-ghc"
69 Ghc Stage1 -> "ghc-stage1"
70 Ghc Stage2 -> "ghc-stage2"
71 Ghc Stage3 -> "ghc-stage3"
72 GhcM stage -> builderKey $ Ghc stage -- synonym for 'Ghc -M'
73 GhcCabal -> "ghc-cabal"
74 GhcCabalHsColour -> builderKey $ GhcCabal -- synonym for 'GhcCabal hscolour'
75 GhcPkg Stage0 -> "system-ghc-pkg"
76 GhcPkg _ -> "ghc-pkg"
77 GhcSplit -> "ghc-split"
78 Happy -> "happy"
79 Haddock -> "haddock"
80 HsColour -> "hscolour"
81 Hsc2Hs -> "hsc2hs"
82 HsCpp -> "hs-cpp"
83 Ld -> "ld"
84 Nm -> "nm"
85 Objdump -> "objdump"
86 Ranlib -> "ranlib"
87 Tar -> "tar"
88 Unlit -> "unlit"
89
90 -- | Determine the location of a 'Builder'
91 -- TODO: Paths to some builders should be determined using 'defaultProgramPath'
92 builderPath :: Builder -> Action FilePath
93 builderPath builder = do
94 path <- askConfigWithDefault (builderKey builder) $
95 putError $ "\nCannot find path to '" ++ (builderKey builder)
96 ++ "' in configuration files."
97 windows <- windowsHost
98 case (path, windows) of
99 ("", _) -> return path
100 (p, True) -> fixAbsolutePathOnWindows (p -<.> exe)
101 (p, False) -> lookupInPathOracle (p -<.> exe)
102
103 getBuilderPath :: Builder -> ReaderT a Action FilePath
104 getBuilderPath = lift . builderPath
105
106 specified :: Builder -> Action Bool
107 specified = fmap (not . null) . builderPath
108
109 -- | Make sure a builder exists on the given path and rebuild it if out of date.
110 -- If 'laxDependencies' is True then we do not rebuild GHC even if it is out of
111 -- date (can save a lot of build time when changing GHC).
112 needBuilder :: Bool -> Builder -> Action ()
113 needBuilder laxDependencies builder = do
114 path <- builderPath builder
115 if laxDependencies && allowOrderOnlyDependency builder
116 then orderOnly [path]
117 else need [path]
118 where
119 allowOrderOnlyDependency :: Builder -> Bool
120 allowOrderOnlyDependency b = case b of
121 Ghc _ -> True
122 GhcM _ -> True
123 _ -> False
124
125 -- Instances for storing in the Shake database
126 instance Binary Builder
127 instance Hashable Builder
128 instance NFData Builder