Add NFData instances
[hadrian.git] / src / Builder.hs
1 {-# LANGUAGE DeriveGeneric #-}
2 module Builder (
3 Builder (..), builderPath, getBuilderPath, specified, needBuilder
4 ) where
5
6 import Base
7 import GHC.Generics (Generic)
8 import Oracles
9 import Stage
10
11 -- A Builder is an external command invoked in separate process using Shake.cmd
12 --
13 -- Ghc Stage0 is the bootstrapping compiler
14 -- Ghc StageN, N > 0, is the one built on stage (N - 1)
15 -- GhcPkg Stage0 is the bootstrapping GhcPkg
16 -- GhcPkg StageN, N > 0, is the one built in Stage0 (TODO: need only Stage1?)
17 -- TODO: add Cpp builders
18 -- TODO: rename Gcc to Cc?
19 -- TODO: do we really need staged builders?
20 data Builder = Alex
21 | Ar
22 | Gcc Stage
23 | GccM Stage
24 | GenPrimopCode
25 | Ghc Stage
26 | GhcCabal
27 | GhcCabalHsColour
28 | GhcLink Stage
29 | GhcM Stage
30 | GhcPkg Stage
31 | GhcSplit
32 | Haddock
33 | Happy
34 | HsColour
35 | HsCpp
36 | Hsc2Hs
37 | Ld
38 | Unlit
39 deriving (Show, Eq, Generic)
40
41 -- Configuration files refer to Builders as follows:
42 builderKey :: Builder -> String
43 builderKey builder = case builder of
44 Alex -> "alex"
45 Ar -> "ar"
46 Gcc Stage0 -> "system-gcc"
47 Gcc _ -> "gcc"
48 GccM stage -> builderKey $ Gcc stage -- synonym for 'Gcc -MM'
49 GenPrimopCode -> "genprimopcode"
50 Ghc Stage0 -> "system-ghc"
51 Ghc Stage1 -> "ghc-stage1"
52 Ghc Stage2 -> "ghc-stage2"
53 Ghc Stage3 -> "ghc-stage3"
54 GhcLink stage -> builderKey $ Ghc stage -- using Ghc as linker
55 GhcM stage -> builderKey $ Ghc stage -- synonym for 'Ghc -M'
56 GhcCabal -> "ghc-cabal"
57 GhcCabalHsColour -> builderKey $ GhcCabal -- synonym for 'GhcCabal hscolour'
58 GhcPkg Stage0 -> "system-ghc-pkg"
59 GhcPkg _ -> "ghc-pkg"
60 GhcSplit -> "ghc-split"
61 Happy -> "happy"
62 Haddock -> "haddock"
63 HsColour -> "hscolour"
64 Hsc2Hs -> "hsc2hs"
65 HsCpp -> "hs-cpp"
66 Ld -> "ld"
67 Unlit -> "unlit"
68
69 builderPath :: Builder -> Action FilePath
70 builderPath builder = do
71 path <- askConfigWithDefault (builderKey builder) $
72 putError $ "\nCannot find path to '" ++ (builderKey builder)
73 ++ "' in configuration files."
74 fixAbsolutePathOnWindows $ if null path then "" else path -<.> exe
75
76 getBuilderPath :: Builder -> ReaderT a Action FilePath
77 getBuilderPath = lift . builderPath
78
79 specified :: Builder -> Action Bool
80 specified = fmap (not . null) . builderPath
81
82 -- Make sure a builder exists on the given path and rebuild it if out of date.
83 -- If laxDependencies is True then we do not rebuild GHC even if it is out of
84 -- date (can save a lot of build time when changing GHC).
85 needBuilder :: Bool -> Builder -> Action ()
86 needBuilder laxDependencies builder = do
87 path <- builderPath builder
88 if laxDependencies && allowOrderOnlyDependency builder
89 then orderOnly [path]
90 else need [path]
91 where
92 allowOrderOnlyDependency :: Builder -> Bool
93 allowOrderOnlyDependency b = case b of
94 Ghc _ -> True
95 GhcM _ -> True
96 _ -> False
97
98 -- On Windows: if the path starts with "/", prepend it with the correct path to
99 -- the root, e.g: "/usr/local/bin/ghc.exe" => "C:/msys/usr/local/bin/ghc.exe".
100 fixAbsolutePathOnWindows :: FilePath -> Action FilePath
101 fixAbsolutePathOnWindows path = do
102 windows <- windowsHost
103 -- Note, below is different from FilePath.isAbsolute:
104 if (windows && "/" `isPrefixOf` path)
105 then do
106 root <- windowsRoot
107 return . unifyPath $ root ++ drop 1 path
108 else
109 return path
110
111 -- Instances for storing in the Shake database
112 instance Binary Builder
113 instance Hashable Builder
114 instance NFData Builder