Rules.hs 4.61 KB
Newer Older
Andrey Mokhov's avatar
Andrey Mokhov committed
1
2
3
4
5
6
7
8
module Rules (
    buildRules, oracleRules, packageTargets, topLevelTargets
    ) where

import qualified Hadrian.Oracles.ArgsHash
import qualified Hadrian.Oracles.DirectoryContents
import qualified Hadrian.Oracles.KeyValue
import qualified Hadrian.Oracles.Path
9

10
import Base
Andrey Mokhov's avatar
Andrey Mokhov committed
11
import Context
Andrey Mokhov's avatar
Andrey Mokhov committed
12
import Expression
Andrey Mokhov's avatar
Andrey Mokhov committed
13
import Flavour
14
import GHC
Andrey Mokhov's avatar
Andrey Mokhov committed
15
16
import qualified Oracles.Dependencies
import qualified Oracles.ModuleFiles
17
18
19
20
21
22
23
24
25
26
27
28
29
import qualified Rules.Compile
import qualified Rules.Data
import qualified Rules.Dependencies
import qualified Rules.Documentation
import qualified Rules.Generate
import qualified Rules.Cabal
import qualified Rules.Configure
import qualified Rules.Gmp
import qualified Rules.Libffi
import qualified Rules.Library
import qualified Rules.Perl
import qualified Rules.Program
import qualified Rules.Register
Andrey Mokhov's avatar
Andrey Mokhov committed
30
import Settings
31
import Settings.Path
Andrey Mokhov's avatar
Andrey Mokhov committed
32
import Target
33

quchen's avatar
quchen committed
34
allStages :: [Stage]
quchen's avatar
quchen committed
35
allStages = [minBound ..]
quchen's avatar
quchen committed
36

Zhen Zhang's avatar
Zhen Zhang committed
37
38
-- | This rule 'need' all top-level build targets
-- or Stage1Only targets
39
topLevelTargets :: Rules ()
Zhen Zhang's avatar
Zhen Zhang committed
40
topLevelTargets = action $ do
41
42
43
44
45
46
47
48
49
50
    let libraryPackages = filter isLibrary (knownPackages \\ [rts, libffi])
    need =<< if stage1Only
             then do
                 libs <- concatForM [Stage0, Stage1] $ \stage ->
                     concatForM libraryPackages $ packageTargets stage
                 prgs <- concatForM programsStage1Only $ packageTargets Stage0
                 return $ libs ++ prgs
             else
                 concatForM allStages $ \stage ->
                     concatForM (knownPackages \\ [rts, libffi]) $ packageTargets stage
51

52
53
54
-- | Return the list of targets associated with a given 'Stage' and 'Package'.
packageTargets :: Stage -> Package -> Action [FilePath]
packageTargets stage pkg = do
Zhen Zhang's avatar
Zhen Zhang committed
55
56
    let context = vanillaContext stage pkg
    activePackages <- interpretInContext context getPackages
57
58
59
60
    if pkg `notElem` activePackages
    then return [] -- Skip inactive packages.
    else if isLibrary pkg
        then do -- Collect all targets of a library package.
Zhen Zhang's avatar
Zhen Zhang committed
61
62
63
            ways <- interpretInContext context getLibraryWays
            libs <- mapM (pkgLibraryFile . Context stage pkg) ways
            docs <- interpretInContext context $ buildHaddock flavour
Andrey Mokhov's avatar
Andrey Mokhov committed
64
            more <- Oracles.Dependencies.libraryTargets context
65
66
67
68
69
            return $ [ pkgSetupConfigFile context | nonCabalContext context ]
                  ++ [ pkgHaddockFile     context | docs && stage == Stage1 ]
                  ++ libs ++ more
        else -- The only target of a program package is the executable.
            maybeToList <$> programPath (programContext stage pkg)
quchen's avatar
quchen committed
70

71
packageRules :: Rules ()
72
packageRules = do
73
74
    -- We cannot register multiple GHC packages in parallel. Also we cannot run
    -- GHC when the package database is being mutated by "ghc-pkg". This is a
75
76
77
78
79
80
    -- classic concurrent read exclusive write (CREW) conflict.
    let maxConcurrentReaders = 1000
    packageDb <- newResource "package-db" maxConcurrentReaders
    let readPackageDb  = [(packageDb, 1)]
        writePackageDb = [(packageDb, maxConcurrentReaders)]

Andrey Mokhov's avatar
Andrey Mokhov committed
81
82
    let contexts        = liftM3 Context        allStages knownPackages allWays
        vanillaContexts = liftM2 vanillaContext allStages knownPackages
Andrey Mokhov's avatar
Andrey Mokhov committed
83
        programContexts = liftM2 programContext allStages knownPackages
84

Andrey Mokhov's avatar
Andrey Mokhov committed
85
    forM_ contexts $ mconcat
86
87
        [ Rules.Compile.compilePackage readPackageDb
        , Rules.Library.buildPackageLibrary ]
88

Zhen Zhang's avatar
Zhen Zhang committed
89
90
91
92
    let dynamicContexts = liftM3 Context [Stage1 ..] knownPackages [dynamic]

    forM_ dynamicContexts Rules.Library.buildDynamicLib

Andrey Mokhov's avatar
Andrey Mokhov committed
93
94
    forM_ programContexts $ Rules.Program.buildProgram readPackageDb

Andrey Mokhov's avatar
Andrey Mokhov committed
95
    forM_ vanillaContexts $ mconcat
96
97
98
99
100
101
        [ Rules.Data.buildPackageData
        , Rules.Dependencies.buildPackageDependencies readPackageDb
        , Rules.Documentation.buildPackageDocumentation
        , Rules.Library.buildPackageGhciLibrary
        , Rules.Generate.generatePackageCode
        , Rules.Register.registerPackage writePackageDb ]
102
103

buildRules :: Rules ()
104
buildRules = do
105
106
107
108
109
110
    Rules.Cabal.cabalRules
    Rules.Configure.configureRules
    Rules.Generate.copyRules
    Rules.Generate.generateRules
    Rules.Gmp.gmpRules
    Rules.Libffi.libffiRules
Andrey Mokhov's avatar
Andrey Mokhov committed
111
    packageRules
112
    Rules.Perl.perlScriptRules
Zhen Zhang's avatar
Zhen Zhang committed
113

Andrey Mokhov's avatar
Andrey Mokhov committed
114
115
116
117
118
119
120
121
oracleRules :: Rules ()
oracleRules = do
    Hadrian.Oracles.ArgsHash.argsHashOracle trackArgument getArgs
    Hadrian.Oracles.DirectoryContents.directoryContentsOracle
    Hadrian.Oracles.KeyValue.keyValueOracle
    Hadrian.Oracles.Path.pathOracle
    Oracles.ModuleFiles.moduleFilesOracle

Zhen Zhang's avatar
Zhen Zhang committed
122
123
programsStage1Only :: [Package]
programsStage1Only =
Andrey Mokhov's avatar
Andrey Mokhov committed
124
125
126
    [ deriveConstants, genprimopcode, hp2ps, runGhc
    , ghcCabal, hpc, dllSplit, ghcPkg, hsc2hs
    , genapply, ghc ]