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
|
{-# LANGUAGE LambdaCase #-}
module Stage (Stage (..), WhichLibs(..), Inplace(..), isStage0, stage0InTree, stage0Boot, allStages,predStage, succStage, stageString) where
import Development.Shake.Classes
import GHC.Generics
-- | A stage refers to a certain compiler in GHC's build process.
--
-- * Stage0 GlobalLibs is for **executables** which are built with the boot compiler
-- and boot compiler packages. For example, this was motivated by needing to
-- build hsc2hs, a build dependency of unix with just the boot toolchain. (See #21634)
--
-- * Stage 0 (InTreeLibs) is built with the bootstrapping compiler, i.e. the one already
-- installed on the user's system. The compiler that is produced during
-- stage 0 is called /stage 1 compiler/. Stage0 executables and libraries are
-- build against the other libraries (in-tree) built by the stage 0 compiler.
--
-- * Stage 1 is built using the stage 1 compiler and all GHC sources. The result
-- is called /stage 2 compiler/ and it has all features of the new GHC.
--
-- * Stage 2 is built using the stage 2 compiler. The result is a compiler
-- fully "built by itself", commonly referred to as /bootstrapping/.
--
-- * Stage 3 is built as a self test. The resulting compiler should have
-- the same object code as the one built in stage 2, which is a good test
-- for the compiler. Since it serves no other purpose than that, the stage 3
-- build is usually omitted in the build process.
data Stage = Stage0 WhichLibs | Stage1 | Stage2 | Stage3
deriving (Show, Eq, Ord, Generic)
{-
Note [Inplace vs Final package databases]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are two package databases we maintain an "inplace" one and a "final" one.
The inplace one is created by pre-configuring all the packages before doing any
building. All GHC invocations to build .hs files will use an inplace package database
for two reasons.
1. To increase parallelism
2. ./hadrian/ghci-multi can use the inplace package db to avoid having to build everything
before starting.
The "inplace" database has .conf files which point directly to the build folders.
The "final" database has a .conf file which points like normall to the install folder.
Therefore when we are building modules, we can start compiling a module as soon as
all it's dependencies are available in the build folder, rather than waiting for the
whole package to finish, be copied and installed like before.
Once we need to do a final link then we need to wait for the "final" versions to
be enabled because then we want to make sure to create objects with the right rpaths and
so on. The "final" .conf has dependencies on all the objects in the package (unlike the "inplace" .conf
which has no such dependencies).
-}
data Inplace = Inplace | Final deriving (Show, Eq, Generic)
instance Binary Inplace
instance Hashable Inplace
instance NFData Inplace
-- | See Note [Stage 0 build plans]
data WhichLibs = GlobalLibs -- ^ Build build tools against the globally installed libraries
| InTreeLibs -- ^ Build the compiler against the in-tree libraries.
deriving (Show, Eq, Ord, Generic)
allStages :: [Stage]
allStages = [Stage0 GlobalLibs, Stage0 InTreeLibs, Stage1, Stage2, Stage3]
stage0InTree, stage0Boot :: Stage
stage0InTree = Stage0 InTreeLibs
stage0Boot = Stage0 GlobalLibs
isStage0 :: Stage -> Bool
isStage0 Stage0 {} = True
isStage0 _ = False
predStage :: Stage -> Stage
predStage Stage1 = stage0InTree
predStage Stage2 = Stage1
predStage Stage3 = Stage2
predStage s = error ("predStage: " ++ show s)
succStage :: Stage -> Stage
succStage (Stage0 {}) = Stage1
succStage Stage1 = Stage2
succStage Stage2 = Stage3
succStage Stage3 = error "succStage: Stage3"
instance Binary Stage
instance Hashable Stage
instance NFData Stage
instance Binary WhichLibs
instance Hashable WhichLibs
instance NFData WhichLibs
-- | Prettyprint a 'Stage'.
stageString :: Stage -> String
stageString = \case
Stage0 GlobalLibs -> "stageBoot"
Stage0 InTreeLibs -> "stage0"
Stage1 -> "stage1"
Stage2 -> "stage2"
Stage3 -> "stage3"
{-
Note [Stage 0 build plans]
~~~~~~~~~~~~~~~~~~~~~~~~~~
The Stage refers to which compiler we will use to perform the builds.
Stage0: Build with the boot toolchain
Stage1: Build with compiler built in stage 0
Stage2: Build with compiler built in stage 1
Stage 0 also has two different package databases.
Stage0 GlobalLibs: Used for building build tool dependencies (hsc2hs, unlit, linters etc)
Mostly using the libraries from the boot compiler.
Stage0 InTreeLibs: Used for building the Stage 1 compiler (ghc executable) and all libraries
needed by that.
The reason for this split is
1. bytestring depends on template-haskell so we need to build bytestring with stage0 (and all
packages which depend on it). This includes unix and hence directory (which depends on unix) but
unix depends on hsc2hs (which depends on directory) and you get a loop in the build
rules if you try to build them all in the same package database.
The solution is to build hsc2hs with the global boot libraries in Stage0 GlobalLibs
2. We want to build linters and other build tools which we don't distribute in a separate
package database so they don't end up in the bindist package database.
-}
|