Build hpc-bin.
[hadrian.git] / src / Builder.hs
1 {-# LANGUAGE DeriveGeneric, LambdaCase #-}
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
10 import GHC.Generics (Generic)
11 import Oracles
12 import Package
13 import Stage
14
15 -- | A 'Builder' is an external command invoked in separate process using 'Shake.cmd'
16 --
17 -- @Ghc Stage0@ is the bootstrapping compiler
18 -- @Ghc StageN@, N > 0, is the one built on stage (N - 1)
19 -- @GhcPkg Stage0@ is the bootstrapping @GhcPkg@
20 -- @GhcPkg StageN@, N > 0, is the one built in Stage0 (TODO: need only Stage1?)
21 -- TODO: Do we really need HsCpp builder? Can't we use a generic Cpp
22 -- builder instead? It would also be used instead of GccM.
23 -- TODO: rename Gcc to CCompiler? We sometimes use gcc and sometimes clang.
24 -- TODO: why are Gcc/GccM staged?
25 data Builder = Alex
26 | Ar
27 | DeriveConstants
28 | Gcc Stage
29 | GccM Stage -- synonym for 'Gcc -MM'
30 | GenApply
31 | GenPrimopCode
32 | Ghc Stage
33 | GhcCabal
34 | GhcCabalHsColour -- synonym for 'GhcCabal hscolour'
35 | GhcM Stage -- synonym for 'Ghc -M'
36 | GhcPkg Stage
37 | Haddock
38 | Happy
39 | Hpc
40 | HsColour
41 | HsCpp
42 | Hsc2Hs
43 | Ld
44 | Make
45 | Nm
46 | Objdump
47 | Patch
48 | Perl
49 | Ranlib
50 | Tar
51 | Unlit
52 deriving (Show, Eq, Generic)
53
54 -- | Some builders are built by this very build system, in which case
55 -- 'builderProvenance' returns the corresponding 'Stage' and GHC 'Package'.
56 builderProvenance :: Builder -> Maybe (Stage, Package)
57 builderProvenance = \case
58 DeriveConstants -> Just (Stage0, deriveConstants)
59 GenApply -> Just (Stage0, genapply)
60 GenPrimopCode -> Just (Stage0, genprimopcode)
61 Ghc stage -> if stage > Stage0 then Just (pred stage, ghc) else Nothing
62 GhcM stage -> builderProvenance $ Ghc stage
63 GhcCabal -> Just (Stage0, ghcCabal)
64 GhcCabalHsColour -> builderProvenance $ GhcCabal
65 GhcPkg stage -> if stage > Stage0 then Just (Stage0, ghcPkg) else Nothing
66 Haddock -> Just (Stage2, haddock)
67 Hpc -> Just (Stage1, hpcBin)
68 Hsc2Hs -> Just (Stage0, hsc2hs)
69 Unlit -> Just (Stage0, unlit)
70 _ -> Nothing
71
72 isInternal :: Builder -> Bool
73 isInternal = isJust . builderProvenance
74
75 isStaged :: Builder -> Bool
76 isStaged = \case
77 (Gcc _) -> True
78 (GccM _) -> True
79 (Ghc _) -> True
80 (GhcM _) -> True
81 (GhcPkg _) -> True
82 _ -> False
83
84 -- TODO: get rid of fromJust
85 -- | Determine the location of a 'Builder'
86 builderPath :: Builder -> Action FilePath
87 builderPath builder = case builderProvenance builder of
88 Just (stage, pkg) -> return . fromJust $ programPath stage pkg
89 Nothing -> do
90 let builderKey = case builder of
91 Alex -> "alex"
92 Ar -> "ar"
93 Gcc Stage0 -> "system-gcc"
94 Gcc _ -> "gcc"
95 GccM Stage0 -> "system-gcc"
96 GccM _ -> "gcc"
97 Ghc Stage0 -> "system-ghc"
98 GhcM Stage0 -> "system-ghc"
99 GhcPkg Stage0 -> "system-ghc-pkg"
100 Happy -> "happy"
101 HsColour -> "hscolour"
102 HsCpp -> "hs-cpp"
103 Ld -> "ld"
104 Make -> "make"
105 Nm -> "nm"
106 Objdump -> "objdump"
107 Patch -> "patch"
108 Perl -> "perl"
109 Ranlib -> "ranlib"
110 Tar -> "tar"
111 _ -> error $ "Cannot determine builderKey for " ++ show builder
112 path <- askConfigWithDefault builderKey . putError $
113 "\nCannot find path to '" ++ builderKey
114 ++ "' in configuration files. Have you forgot to run configure?"
115 windows <- windowsHost
116 case (path, windows) of
117 ("", _ ) -> return path
118 (p , True ) -> fixAbsolutePathOnWindows (p -<.> exe)
119 (p , False) -> lookupInPath p
120
121 getBuilderPath :: Builder -> ReaderT a Action FilePath
122 getBuilderPath = lift . builderPath
123
124 specified :: Builder -> Action Bool
125 specified = fmap (not . null) . builderPath
126
127 -- | Make sure a builder exists on the given path and rebuild it if out of date.
128 -- If 'laxDependencies' is True then we do not rebuild GHC even if it is out of
129 -- date (can save a lot of build time when changing GHC).
130 needBuilder :: Bool -> Builder -> Action ()
131 needBuilder laxDependencies builder = when (isInternal builder) $ do
132 path <- builderPath builder
133 if laxDependencies && allowOrderOnlyDependency builder
134 then orderOnly [path]
135 else need [path]
136 where
137 allowOrderOnlyDependency :: Builder -> Bool
138 allowOrderOnlyDependency = \case
139 Ghc _ -> True
140 GhcM _ -> True
141 _ -> False
142
143 -- Instances for storing in the Shake database
144 instance Binary Builder
145 instance Hashable Builder
146 instance NFData Builder