summaryrefslogtreecommitdiff
path: root/hadrian/src/Base.hs
blob: 9e096f412b4636c073ae3d0db3d63c8c7dd9f308 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
{-# LANGUAGE CPP #-}

module Base (
    -- * General utilities
    module Control.Applicative,
    module Control.Monad.Extra,
    module Data.List.Extra,
    module Data.Maybe,
    module Data.Semigroup,
    module Hadrian.Utilities,

    -- * Shake
    module Development.Shake,
    module Development.Shake.Classes,
    module Development.Shake.FilePath,
    module Development.Shake.Util,

    -- * Basic data types
    module Hadrian.Package,
    module Stage,
    module Way,

    -- * Files
    configH, ghcVersionH,

    -- * Paths
    hadrianPath, configPath, configFile, sourcePath, shakeFilesDir,
    stageBinPath, stageLibPath, templateHscPath,
    ghcBinDeps, ghcLibDeps, includesDependencies, haddockDeps,
    relativePackageDbPath, packageDbPath, packageDbStamp, mingwStamp,
    ) where

import Control.Applicative
import Control.Monad.Extra
import Control.Monad.Reader
import Data.List.Extra
import Data.Maybe
import Data.Semigroup
#if MIN_VERSION_shake(0,19,0)
import Development.Shake hiding (unit, Normal)
#else
import Development.Shake hiding (unit, (*>), Normal)
#endif
import Development.Shake.Classes
import Development.Shake.FilePath
import Development.Shake.Util
import Hadrian.Oracles.DirectoryContents
import Hadrian.Utilities
import Hadrian.Package

import Stage
import Way

-- | Hadrian lives in the 'hadrianPath' directory of the GHC tree.
hadrianPath :: FilePath
hadrianPath = "hadrian"

-- TODO: Move this to build directory?
-- | Path to system configuration files, such as 'configFile'.
configPath :: FilePath
configPath = hadrianPath -/- "cfg"

-- | Path to the system configuration file generated by the @configure@ script.
configFile :: FilePath
configFile = configPath -/- "system.config"

-- | Path to source files of the build system, e.g. this file is located at
-- @sourcePath -/- "Base.hs"@. We use this to track some of the source files.
sourcePath :: FilePath
sourcePath = hadrianPath -/- "src"

-- TODO: Change @mk/config.h@ to @shake-build/cfg/config.h@.
-- | Path to the generated @mk/config.h@ file.
configH :: FilePath
configH = "mk/config.h"

ghcVersionH :: Stage -> Action FilePath
ghcVersionH stage = stageLibPath stage <&> (-/- "ghcversion.h")

-- | The directory in 'buildRoot' containing the Shake database and other
-- auxiliary files generated by Hadrian.
shakeFilesDir :: FilePath
shakeFilesDir = "hadrian"

-- | Path to the package database for a given build stage, relative to the build
-- root.
relativePackageDbPath :: Stage -> FilePath
relativePackageDbPath stage = stageString stage -/- "lib/package.conf.d"

-- | Path to the package database used in a given 'Stage', including
--   the build root.
packageDbPath :: Stage -> Action FilePath
packageDbPath stage = buildRoot <&> (-/- relativePackageDbPath stage)

-- | We use a stamp file to track the existence of a package database.
packageDbStamp :: FilePath
packageDbStamp = ".stamp"

-- | @bin@ directory for the given 'Stage' (including the build root)
stageBinPath :: Stage -> Action FilePath
stageBinPath stage = buildRoot <&> (-/- stageString stage -/- "bin")

-- | @lib@ directory for the given 'Stage' (including the build root)
stageLibPath :: Stage -> Action FilePath
stageLibPath stage = buildRoot <&> (-/- stageString stage -/- "lib")

-- | Files the GHC library depends on
ghcLibDeps :: Stage -> Action [FilePath]
ghcLibDeps stage = mapM (\f -> stageLibPath stage <&> (-/- f))
    [ "llvm-targets"
    , "llvm-passes"
    , "platformConstants"
    , "settings"
    ]

-- | Files the GHC binary depends on.
ghcBinDeps :: Stage -> Action [FilePath]
ghcBinDeps stage = mapM (\f -> stageLibPath stage <&> (-/- f))
    [ "ghc-usage.txt"
    , "ghci-usage.txt"
    ]

includesDependencies :: Stage -> Action [FilePath]
includesDependencies stage = do
    p <- stageLibPath stage
    pure $ (p -/-) <$>
      [ "ghcautoconf.h", "ghcplatform.h", "ghcversion.h" ]

-- | Files the `haddock` binary depends on
haddockDeps :: Stage -> Action [FilePath]
haddockDeps stage = do
    let resdir = "utils/haddock/haddock-api/resources"
    latexResources <- directoryContents matchAll (resdir -/- "latex")
    htmlResources  <- directoryContents matchAll (resdir -/- "html")

    haddockLib <- stageLibPath stage
    return $ [ haddockLib -/- makeRelative resdir f
             | f <- latexResources ++ htmlResources ]

-- ref: utils/hsc2hs/ghc.mk
-- | Path to 'hsc2hs' template.
templateHscPath :: Stage -> Action FilePath
templateHscPath stage = stageLibPath stage <&> (-/- "template-hsc.h")

-- | We use this stamp file to track whether we've moved the mingw toolchain
--   under the build root (to make it accessible to the GHCs we build on
--   Windows). See "Rules.Program".
mingwStamp :: FilePath
mingwStamp = "mingw" -/- ".stamp"