Expression: Don't re-export Base
[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: Do we really need HsCpp builder? Can't we use a generic Cpp
18 -- builder instead? It would also be used instead of GccM.
19 -- TODO: rename Gcc to CCompiler? We sometimes use gcc and sometimes clang.
20 -- TODO: why are Gcc/GccM staged?
21 data Builder = Alex
22 | Ar
23 | DeriveConstants
24 | Gcc Stage
25 | GccM Stage
26 | GenPrimopCode
27 | Ghc Stage
28 | GhcCabal
29 | GhcCabalHsColour
30 | GhcM Stage
31 | GhcPkg Stage
32 | GhcSplit
33 | Haddock
34 | Happy
35 | HsColour
36 | HsCpp
37 | Hsc2Hs
38 | Ld
39 | Nm
40 | Objdump
41 | Unlit
42 deriving (Show, Eq, Generic)
43
44 -- Configuration files refer to Builders as follows:
45 builderKey :: Builder -> String
46 builderKey builder = case builder of
47 Alex -> "alex"
48 Ar -> "ar"
49 DeriveConstants -> "derive-constants"
50 Gcc Stage0 -> "system-gcc"
51 Gcc _ -> "gcc"
52 GccM stage -> builderKey $ Gcc stage -- synonym for 'Gcc -MM'
53 GenPrimopCode -> "genprimopcode"
54 Ghc Stage0 -> "system-ghc"
55 Ghc Stage1 -> "ghc-stage1"
56 Ghc Stage2 -> "ghc-stage2"
57 Ghc Stage3 -> "ghc-stage3"
58 GhcM stage -> builderKey $ Ghc stage -- synonym for 'Ghc -M'
59 GhcCabal -> "ghc-cabal"
60 GhcCabalHsColour -> builderKey $ GhcCabal -- synonym for 'GhcCabal hscolour'
61 GhcPkg Stage0 -> "system-ghc-pkg"
62 GhcPkg _ -> "ghc-pkg"
63 GhcSplit -> "ghc-split"
64 Happy -> "happy"
65 Haddock -> "haddock"
66 HsColour -> "hscolour"
67 Hsc2Hs -> "hsc2hs"
68 HsCpp -> "hs-cpp"
69 Ld -> "ld"
70 Nm -> "nm"
71 Objdump -> "objdump"
72 Unlit -> "unlit"
73
74 -- TODO: Paths to some builders should be determined using defaultProgramPath
75 builderPath :: Builder -> Action FilePath
76 builderPath builder = do
77 path <- askConfigWithDefault (builderKey builder) $
78 putError $ "\nCannot find path to '" ++ (builderKey builder)
79 ++ "' in configuration files."
80 fixAbsolutePathOnWindows $ if null path then "" else path -<.> exe
81
82 getBuilderPath :: Builder -> ReaderT a Action FilePath
83 getBuilderPath = lift . builderPath
84
85 specified :: Builder -> Action Bool
86 specified = fmap (not . null) . builderPath
87
88 -- Make sure a builder exists on the given path and rebuild it if out of date.
89 -- If laxDependencies is True then we do not rebuild GHC even if it is out of
90 -- date (can save a lot of build time when changing GHC).
91 needBuilder :: Bool -> Builder -> Action ()
92 needBuilder laxDependencies builder = do
93 path <- builderPath builder
94 if laxDependencies && allowOrderOnlyDependency builder
95 then orderOnly [path]
96 else need [path]
97 where
98 allowOrderOnlyDependency :: Builder -> Bool
99 allowOrderOnlyDependency b = case b of
100 Ghc _ -> True
101 GhcM _ -> True
102 _ -> False
103
104 -- TODO: this is fragile, e.g. we currently only handle C: drive
105 -- On Windows:
106 -- * if the path starts with "/c/" change the prefix to "C:/"
107 -- * otherwise, if the path starts with "/", prepend it with the correct path
108 -- to the root, e.g: "/usr/local/bin/ghc.exe" => "C:/msys/usr/local/bin/ghc.exe"
109 fixAbsolutePathOnWindows :: FilePath -> Action FilePath
110 fixAbsolutePathOnWindows path = do
111 windows <- windowsHost
112 -- Note, below is different from FilePath.isAbsolute:
113 if (windows && "/" `isPrefixOf` path)
114 then do
115 if ("/c/" `isPrefixOf` path)
116 then return $ "C:" ++ drop 2 path
117 else do
118 root <- windowsRoot
119 return . unifyPath $ root ++ drop 1 path
120 else
121 return path
122
123 -- Instances for storing in the Shake database
124 instance Binary Builder
125 instance Hashable Builder
126 instance NFData Builder