Lookup builder in PATH if they are given without path.
[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 let path' = if null path then "" else path -<.> exe in
99 (if windows then fixAbsolutePathOnWindows else lookupInPath) path'
100
101 getBuilderPath :: Builder -> ReaderT a Action FilePath
102 getBuilderPath = lift . builderPath
103
104 specified :: Builder -> Action Bool
105 specified = fmap (not . null) . builderPath
106
107 -- | Make sure a builder exists on the given path and rebuild it if out of date.
108 -- If 'laxDependencies' is True then we do not rebuild GHC even if it is out of
109 -- date (can save a lot of build time when changing GHC).
110 needBuilder :: Bool -> Builder -> Action ()
111 needBuilder laxDependencies builder = do
112 path <- builderPath builder
113 if laxDependencies && allowOrderOnlyDependency builder
114 then orderOnly [path]
115 else need [path]
116 where
117 allowOrderOnlyDependency :: Builder -> Bool
118 allowOrderOnlyDependency b = case b of
119 Ghc _ -> True
120 GhcM _ -> True
121 _ -> False
122
123 -- Instances for storing in the Shake database
124 instance Binary Builder
125 instance Hashable Builder
126 instance NFData Builder