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

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

Andrey Mokhov's avatar
Andrey Mokhov committed
8
import Context
Andrey Mokhov's avatar
Andrey Mokhov committed
9
import Expression
Andrey Mokhov's avatar
Andrey Mokhov committed
10
import Flavour
11
import GHC
Andrey Mokhov's avatar
Andrey Mokhov committed
12
import qualified Oracles.ModuleFiles
13
14
15
16
17
18
19
20
21
22
23
24
25
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
26
import Settings
27
import Settings.Path
Andrey Mokhov's avatar
Andrey Mokhov committed
28
import Target
29
import Utilities
30

quchen's avatar
quchen committed
31
allStages :: [Stage]
quchen's avatar
quchen committed
32
allStages = [minBound ..]
quchen's avatar
quchen committed
33

Zhen Zhang's avatar
Zhen Zhang committed
34
35
-- | This rule 'need' all top-level build targets
-- or Stage1Only targets
36
topLevelTargets :: Rules ()
Zhen Zhang's avatar
Zhen Zhang committed
37
topLevelTargets = action $ do
38
39
40
41
42
43
44
45
46
47
    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
48

49
50
51
-- | 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
52
53
    let context = vanillaContext stage pkg
    activePackages <- interpretInContext context getPackages
54
55
56
57
    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
58
59
60
            ways <- interpretInContext context getLibraryWays
            libs <- mapM (pkgLibraryFile . Context stage pkg) ways
            docs <- interpretInContext context $ buildHaddock flavour
61
            more <- libraryTargets context
62
63
64
65
66
            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
67

68
packageRules :: Rules ()
69
packageRules = do
70
71
    -- 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
72
73
74
75
76
77
    -- 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
78
79
    let contexts        = liftM3 Context        allStages knownPackages allWays
        vanillaContexts = liftM2 vanillaContext allStages knownPackages
Andrey Mokhov's avatar
Andrey Mokhov committed
80
        programContexts = liftM2 programContext allStages knownPackages
81

Andrey Mokhov's avatar
Andrey Mokhov committed
82
    forM_ contexts $ mconcat
83
84
        [ Rules.Compile.compilePackage readPackageDb
        , Rules.Library.buildPackageLibrary ]
85

Zhen Zhang's avatar
Zhen Zhang committed
86
87
88
89
    let dynamicContexts = liftM3 Context [Stage1 ..] knownPackages [dynamic]

    forM_ dynamicContexts Rules.Library.buildDynamicLib

Andrey Mokhov's avatar
Andrey Mokhov committed
90
91
    forM_ programContexts $ Rules.Program.buildProgram readPackageDb

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

buildRules :: Rules ()
101
buildRules = do
102
103
104
105
106
107
    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
108
    packageRules
109
    Rules.Perl.perlScriptRules
Zhen Zhang's avatar
Zhen Zhang committed
110

Andrey Mokhov's avatar
Andrey Mokhov committed
111
112
113
114
115
116
117
118
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
119
120
programsStage1Only :: [Package]
programsStage1Only =
Andrey Mokhov's avatar
Andrey Mokhov committed
121
122
123
    [ deriveConstants, genprimopcode, hp2ps, runGhc
    , ghcCabal, hpc, dllSplit, ghcPkg, hsc2hs
    , genapply, ghc ]