Rules.hs 4.47 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
            ways <- interpretInContext context getLibraryWays
            libs <- mapM (pkgLibraryFile . Context stage pkg) ways
60
            docs <- interpretInContext context =<< buildHaddock <$> flavour
61
            more <- libraryTargets context
62 63 64 65
            return $ [ pkgSetupConfigFile context | nonCabalContext context ]
                  ++ [ pkgHaddockFile     context | docs && stage == Stage1 ]
                  ++ libs ++ more
        else -- The only target of a program package is the executable.
66
            fmap 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
80

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

Zhen Zhang's avatar
Zhen Zhang committed
85 86 87
    let dynamicContexts = liftM3 Context [Stage1 ..] knownPackages [dynamic]
    forM_ dynamicContexts Rules.Library.buildDynamicLib

Andrey Mokhov's avatar
Andrey Mokhov committed
88
    forM_ vanillaContexts $ mconcat
89 90 91 92 93
        [ Rules.Data.buildPackageData
        , Rules.Dependencies.buildPackageDependencies readPackageDb
        , Rules.Documentation.buildPackageDocumentation
        , Rules.Library.buildPackageGhciLibrary
        , Rules.Generate.generatePackageCode
94
        , Rules.Program.buildProgram readPackageDb
95
        , Rules.Register.registerPackage writePackageDb ]
96 97

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

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