Rules.hs 4.04 KB
Newer Older
1
module Rules (topLevelTargets, packageTargets, buildRules) where
2

3
import Base
Andrey Mokhov's avatar
Andrey Mokhov committed
4
import Context
Andrey Mokhov's avatar
Andrey Mokhov committed
5
import Expression
Andrey Mokhov's avatar
Andrey Mokhov committed
6
import Flavour
7
import GHC
8
9
10
11
12
13
14
15
16
17
18
19
20
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
21
import Oracles.Dependencies
Andrey Mokhov's avatar
Andrey Mokhov committed
22
import Settings
23
import Settings.Path
24

quchen's avatar
quchen committed
25
allStages :: [Stage]
quchen's avatar
quchen committed
26
allStages = [minBound ..]
quchen's avatar
quchen committed
27

Zhen Zhang's avatar
Zhen Zhang committed
28
29
-- | This rule 'need' all top-level build targets
-- or Stage1Only targets
30
topLevelTargets :: Rules ()
Zhen Zhang's avatar
Zhen Zhang committed
31
topLevelTargets = action $ do
32
33
34
35
36
37
38
39
40
41
    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
42

43
44
45
-- | 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
46
47
    let context = vanillaContext stage pkg
    activePackages <- interpretInContext context getPackages
48
49
50
51
    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
52
53
54
            ways <- interpretInContext context getLibraryWays
            libs <- mapM (pkgLibraryFile . Context stage pkg) ways
            docs <- interpretInContext context $ buildHaddock flavour
55
56
57
58
59
60
            more <- libraryTargets context
            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
61

62
packageRules :: Rules ()
63
packageRules = do
64
65
    -- 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
66
67
68
69
70
71
    -- 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
72
73
    let contexts        = liftM3 Context        allStages knownPackages allWays
        vanillaContexts = liftM2 vanillaContext allStages knownPackages
Andrey Mokhov's avatar
Andrey Mokhov committed
74
        programContexts = liftM2 programContext allStages knownPackages
75

Andrey Mokhov's avatar
Andrey Mokhov committed
76
    forM_ contexts $ mconcat
77
78
        [ Rules.Compile.compilePackage readPackageDb
        , Rules.Library.buildPackageLibrary ]
79

Zhen Zhang's avatar
Zhen Zhang committed
80
81
82
83
    let dynamicContexts = liftM3 Context [Stage1 ..] knownPackages [dynamic]

    forM_ dynamicContexts Rules.Library.buildDynamicLib

Andrey Mokhov's avatar
Andrey Mokhov committed
84
85
    forM_ programContexts $ Rules.Program.buildProgram readPackageDb

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

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

programsStage1Only :: [Package]
programsStage1Only =
  [ deriveConstants, genprimopcode, hp2ps, runGhc
  , ghcCabal, hpc, dllSplit, ghcPkg, hsc2hs
  , genapply, ghc ]