Detect the right patch command and use it when building gmp.
[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 | Haddock
36 | Happy
37 | HsColour
38 | HsCpp
39 | Hsc2Hs
40 | Ld
41 | Nm
42 | Objdump
43 | Patch
44 | Perl
45 | Ranlib
46 | Tar
47 | Unlit
48 deriving (Show, Eq, Generic)
49
50 isStaged :: Builder -> Bool
51 isStaged (Gcc _) = True
52 isStaged (GccM _) = True
53 isStaged (Ghc _) = True
54 isStaged (GhcM _) = True
55 isStaged (GhcPkg _) = True
56 isStaged _ = False
57
58 -- Configuration files refer to Builders as follows:
59 builderKey :: Builder -> String
60 builderKey builder = case builder of
61 Alex -> "alex"
62 Ar -> "ar"
63 DeriveConstants -> "derive-constants"
64 Gcc Stage0 -> "system-gcc"
65 Gcc _ -> "gcc"
66 GccM stage -> builderKey $ Gcc stage -- synonym for 'Gcc -MM'
67 GenApply -> "genapply"
68 GenPrimopCode -> "genprimopcode"
69 Ghc Stage0 -> "system-ghc"
70 Ghc Stage1 -> "ghc-stage1"
71 Ghc Stage2 -> "ghc-stage2"
72 Ghc Stage3 -> "ghc-stage3"
73 GhcM stage -> builderKey $ Ghc stage -- synonym for 'Ghc -M'
74 GhcCabal -> "ghc-cabal"
75 GhcCabalHsColour -> builderKey $ GhcCabal -- synonym for 'GhcCabal hscolour'
76 GhcPkg Stage0 -> "system-ghc-pkg"
77 GhcPkg _ -> "ghc-pkg"
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 Patch -> "patch"
87 Perl -> "perl"
88 Ranlib -> "ranlib"
89 Tar -> "tar"
90 Unlit -> "unlit"
91
92 -- | Determine the location of a 'Builder'
93 -- TODO: Paths to some builders should be determined using 'defaultProgramPath'
94 builderPath :: Builder -> Action FilePath
95 builderPath builder = do
96 path <- askConfigWithDefault (builderKey builder) $
97 putError $ "\nCannot find path to '" ++ (builderKey builder)
98 ++ "' in configuration files."
99 windows <- windowsHost
100 case (path, windows) of
101 ("", _) -> return path
102 (p, True) -> fixAbsolutePathOnWindows (p -<.> exe)
103 (p, False) -> lookupInPath (p -<.> exe)
104
105 getBuilderPath :: Builder -> ReaderT a Action FilePath
106 getBuilderPath = lift . builderPath
107
108 specified :: Builder -> Action Bool
109 specified = fmap (not . null) . builderPath
110
111 -- | Make sure a builder exists on the given path and rebuild it if out of date.
112 -- If 'laxDependencies' is True then we do not rebuild GHC even if it is out of
113 -- date (can save a lot of build time when changing GHC).
114 needBuilder :: Bool -> Builder -> Action ()
115 needBuilder laxDependencies builder = whenM (specified builder) $ do
116 path <- builderPath builder
117 if laxDependencies && allowOrderOnlyDependency builder
118 then orderOnly [path]
119 else need [path]
120 where
121 allowOrderOnlyDependency :: Builder -> Bool
122 allowOrderOnlyDependency b = case b of
123 Ghc _ -> True
124 GhcM _ -> True
125 _ -> False
126
127 -- Instances for storing in the Shake database
128 instance Binary Builder
129 instance Hashable Builder
130 instance NFData Builder