Update Hadrian
[ghc.git] / hadrian / src / Rules.hs
1 module Rules (buildRules, oracleRules, packageTargets, topLevelTargets) where
2
3 import qualified Hadrian.Oracles.ArgsHash
4 import qualified Hadrian.Oracles.DirectoryContents
5 import qualified Hadrian.Oracles.Path
6 import qualified Hadrian.Oracles.TextFile
7
8 import Expression
9 import qualified Oracles.ModuleFiles
10 import qualified Rules.Compile
11 import qualified Rules.PackageData
12 import qualified Rules.Dependencies
13 import qualified Rules.Documentation
14 import qualified Rules.Generate
15 import qualified Rules.Configure
16 import qualified Rules.Gmp
17 import qualified Rules.Libffi
18 import qualified Rules.Library
19 import qualified Rules.Program
20 import qualified Rules.Register
21 import Settings
22 import Target
23 import UserSettings
24 import Utilities
25
26 allStages :: [Stage]
27 allStages = [minBound ..]
28
29 -- | This rule calls 'need' on all top-level build targets, respecting the
30 -- 'Stage1Only' flag.
31 topLevelTargets :: Rules ()
32 topLevelTargets = action $ do
33 let libraryPackages = filter isLibrary (knownPackages \\ [libffi])
34 need =<< if stage1Only
35 then do
36 libs <- concatForM [Stage0, Stage1] $ \stage ->
37 concatForM libraryPackages $ packageTargets False stage
38 prgs <- concatForM programsStage1Only $ packageTargets False Stage0
39 return $ libs ++ prgs ++ inplaceLibCopyTargets
40 else do
41 targets <- concatForM allStages $ \stage ->
42 concatForM (knownPackages \\ [libffi]) $
43 packageTargets False stage
44 return $ targets ++ inplaceLibCopyTargets
45
46 -- TODO: Get rid of the @includeGhciLib@ hack.
47 -- | Return the list of targets associated with a given 'Stage' and 'Package'.
48 -- By setting the Boolean parameter to False it is possible to exclude the GHCi
49 -- library from the targets, and avoid running @ghc-cabal@ to determine wether
50 -- GHCi library needs to be built for this package. We typically want to set
51 -- this parameter to True, however it is important to set it to False when
52 -- computing 'topLevelTargets', as otherwise the whole build gets sequentialised
53 -- because we need to run @ghc-cabal@ in the order respecting package dependencies.
54 packageTargets :: Bool -> Stage -> Package -> Action [FilePath]
55 packageTargets includeGhciLib stage pkg = do
56 let context = vanillaContext stage pkg
57 activePackages <- stagePackages stage
58 if pkg `notElem` activePackages
59 then return [] -- Skip inactive packages.
60 else if isLibrary pkg
61 then do -- Collect all targets of a library package.
62 let pkgWays = if pkg == rts then getRtsWays else getLibraryWays
63 ways <- interpretInContext context pkgWays
64 libs <- mapM (pkgLibraryFile . Context stage pkg) ways
65 more <- libraryTargets includeGhciLib context
66 setup <- pkgSetupConfigFile context
67 return $ [ setup | not (nonCabalContext context) ] ++ libs ++ more
68 else do -- The only target of a program package is the executable.
69 prgContext <- programContext stage pkg
70 prgPath <- programPath prgContext
71 return [prgPath]
72
73 packageRules :: Rules ()
74 packageRules = do
75 -- We cannot register multiple GHC packages in parallel. Also we cannot run
76 -- GHC when the package database is being mutated by "ghc-pkg". This is a
77 -- classic concurrent read exclusive write (CREW) conflict.
78 let maxConcurrentReaders = 1000
79 packageDb <- newResource "package-db" maxConcurrentReaders
80 let readPackageDb = [(packageDb, 1)]
81 writePackageDb = [(packageDb, maxConcurrentReaders)]
82
83 let contexts = liftM3 Context allStages knownPackages allWays
84 vanillaContexts = liftM2 vanillaContext allStages knownPackages
85
86 forM_ contexts $ mconcat
87 [ Rules.Compile.compilePackage readPackageDb
88 , Rules.Library.buildPackageLibrary ]
89
90 let dynamicContexts = liftM3 Context [Stage1 ..] knownPackages [dynamic]
91 forM_ dynamicContexts Rules.Library.buildDynamicLib
92
93 forM_ (filter isProgram knownPackages) $
94 Rules.Program.buildProgram readPackageDb
95
96 forM_ vanillaContexts $ mconcat
97 [ Rules.PackageData.buildPackageData
98 , Rules.Dependencies.buildPackageDependencies readPackageDb
99 , Rules.Documentation.buildPackageDocumentation
100 , Rules.Library.buildPackageGhciLibrary
101 , Rules.Generate.generatePackageCode
102 , Rules.Register.registerPackage writePackageDb ]
103
104 buildRules :: Rules ()
105 buildRules = do
106 Rules.Configure.configureRules
107 Rules.Generate.copyRules
108 Rules.Generate.generateRules
109 Rules.Gmp.gmpRules
110 Rules.Libffi.libffiRules
111 packageRules
112
113 oracleRules :: Rules ()
114 oracleRules = do
115 Hadrian.Oracles.ArgsHash.argsHashOracle trackArgument getArgs
116 Hadrian.Oracles.DirectoryContents.directoryContentsOracle
117 Hadrian.Oracles.Path.pathOracle
118 Hadrian.Oracles.TextFile.textFileOracle
119 Oracles.ModuleFiles.moduleFilesOracle
120
121 programsStage1Only :: [Package]
122 programsStage1Only = [ deriveConstants, genapply, genprimopcode, ghc, ghcCabal
123 , ghcPkg, hp2ps, hpc, hsc2hs, runGhc ]