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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
|
# User settings
You can customise Hadrian by copying the file `hadrian/src/UserSettings.hs` to
`hadrian/UserSettings.hs` and overriding the default build settings (if you don't
copy the file your changes will be tracked by `git` and you can accidentally commit
them). Here we document currently supported settings.
## Build flavour
Build _flavour_ is a collection of build settings that fully define a GHC build
(see `src/Flavour.hs`):
```haskell
data Flavour = Flavour {
-- | Flavour name, to select this flavour from command line.
name :: String,
-- | Use these command line arguments.
args :: Args,
-- | Build these packages.
packages :: Stage -> Action [Package],
-- | Either 'integerGmp' or 'integerSimple'.
integerLibrary :: Action Package,
-- | Build libraries these ways.
libraryWays :: Ways,
-- | Build RTS these ways.
rtsWays :: Ways,
-- | Build dynamic GHC programs.
dynamicGhcPrograms :: Action Bool,
-- | Enable GHCi debugger.
ghciWithDebugger :: Bool,
-- | Build profiled GHC.
ghcProfiled :: Bool,
-- | Build GHC with debug information.
ghcDebugged :: Bool
-- | Whether to build docs and which ones
-- (haddocks, user manual, haddock manual)
ghcDocs :: Action DocTargets }
```
Hadrian provides several built-in flavours (`default`, `quick`, and a few
others; see `hadrian/doc/flavours.md`), which can be activated from the command line,
e.g. by passing `--flavour=quick`. Users can define new build flavours by adding them
to `userFlavours` list:
```haskell
-- | User-defined build flavours. See 'userFlavour' as an example.
userFlavours :: [Flavour]
userFlavours = [userFlavour] -- Add more build flavours if need be.
-- | This is an example user-defined build flavour. Feel free to modify it and
-- use by passing @--flavour=user@ from the command line.
userFlavour :: Flavour
userFlavour = defaultFlavour { name = "user" } -- Modify other settings here.
```
Now `--flavour=user` will run Hadrian with `userFlavour` settings.
When no `--flavour` argument is passed to hadrian, it will use the
`default` one. You can however change this, and for example make
the "fallback" flavour be `user`, by changing `userDefaultFlavour`:
``` haskell
userDefaultFlavour :: String
-- before:
-- userDefaultFlavour = "default"
-- now:
userDefaultFlavour = "user"
```
This saves you from having to type `build --flavour=user [...]`
every time, allowing you to _persist_ the choice of flavour.
In the
following sections we look at specific fields of the `Flavour` record in
more detail. Note: `defaultFlavour`, as well as its individual fields such
as `defaultArgs`, `defaultPackages`, etc. that we use below, are defined in module
`Settings.Default`.
## Command line arguments
One of the key features of Hadrian is that users can easily modify any build command.
The build system will detect the change and will rerun all affected build rules during
the next build, without requiring a full rebuild.
For example, here is how to pass an extra argument `-O0` to all invocations of
GHC when compiling package `cabal`:
```haskell
userFlavour :: Flavour
userFlavour = defaultFlavour { name = "user", args = defaultArgs <> userArgs }
userArgs :: Args
userArgs = builder Ghc ? package cabal ? arg "-O0"
```
Builders such as `Ghc` are defined in `src/Builder.hs`, and all packages that
are currently built as part of the GHC are defined in `src/GHC.hs`.
You can combine several custom command line settings using `mconcat`:
```haskell
userArgs :: Args
userArgs = mconcat
[ builder Ghc ? package cabal ? arg "-O0"
, package rts ? input "//PrimOps.c" ? pure ["-fno-PIC", "-static"] ]
```
You can match any combination of the `builder`, `stage`, `package`, `way`, `input`
and `output` predicates when specifying custom command line arguments. File
patterns such as `"//Prelude.*"` can be used when matching input and output files,
where `//` matches an arbitrary number of path components and `*` matches an entire
path component, excluding any separators.
### Enabling -Werror
It is useful to enable `-Werror` when building GHC as this setting is
used in the CI to ensure a warning free build. The `werror` function can be
used to easily modify a flavour to turn this setting on.
```
devel2WerrorFlavour :: Flavour
devel2WerrorFlavour = werror (developmentFlavour Stage2)
```
## Packages
Users can add and remove packages from particular build stages. As an example,
below we add package `base` to Stage0 and remove package `haskeline` from Stage1:
```haskell
...
import Packages
...
userFlavour :: Flavour
userFlavour = defaultFlavour { name = "user", packages = modifiedPackages }
modifiedPackages :: Stage -> Action [Package]
modifiedPackages stage = do
packages <- defaultPackages stage
return $ case stage of
Stage0 -> packages ++ [base]
Stage1 -> packages \\ [haskeline]
_ -> packages
```
If you are working on a new GHC package you need to let Hadrian know about it
by adding it to `userPackages`:
```haskell
userPackages :: [Package]
userPackages = [userPackage]
-- An example package that lives in "libraries/user-package" directory.
userPackage :: Package
userPackage = library "user-package"
```
You will also need to add `userPackage` to a specific build stage by modifying
the `packages` setting of the user flavour as otherwise it will not be built.
You can choose which integer library to use when builing GHC using the
`integerLibrary` setting of the build flavour. Possible values are: `integerGmp`
(default) and `integerSimple`.
```haskell
userFlavour :: Flavour
userFlavour = defaultFlavour { name = "user", integerLibrary = pure integerSimple }
```
### Specifying the final stage to build
The `finalStage` variable can be set to indicate after which stage we should
stop the compilation pipeline. By default it is set to `Stage2` which indicates
that we will build everything which uses the `Stage1` `ghc` and then stop.
```
finalStage :: Stage
finalStage = Stage2
```
Using this mechanism we can also build a `Stage3` compiler by setting
`finalStage = Stage3` or just a `Stage1` compiler by setting
`finalStage = Stage1`.
## Build ways
Packages can be built in a number of ways, such as `vanilla`, `profiling` (with
profiling information enabled), and many others as defined in `src/Way.hs`. You
can change the default build ways by modifying `libraryWays` and `rtsWays` fields
of the `Flavour` record as required. As an example, below we remove `profiling`
from the list of library ways:
```haskell
noProfilingFlavour :: Flavour
noProfilingFlavour = defaultFlavour
{ name = "no-profiling"
, libraryWays = remove [profiling] defaultLibraryWays
, ghcProfiled = False } -- Can't build profiled GHC without profiled libraries
```
Note that `rtsWays` is computed from `libraryWays` by default, therefore the above
change will lead to the removal of `threadedProfiling` way from `rtsWays`. To
change this behaviour, you can override the default `rtsWays` setting.
Similarly, if we want to completely turn off dynamic linking, we can define a custom
`Flavour` to this effect:
``` haskell
noDynamicFlavour :: Flavour
noDynamicFlavour = defaultFlavour
{ name = "no-dynamic"
, libraryWays = remove [dynamic] defaultLibraryWays }
```
## Verbose command lines
By default Hadrian does not print full command lines during the build process
and instead prints short human readable digests for each executed command. You
can suppress this behaviour completely or partially using `verboseCommand` setting:
```haskell
-- | Set to 'True' to print full command lines during the build process. Note:
-- this is a 'Predicate', hence you can enable verbose output only for certain
-- targets, e.g.: @verboseCommand = package ghcPrim@.
verboseCommand :: Predicate
verboseCommand = do
verbosity <- expr getVerbosity
return $ verbosity >= Loud
```
For example, to print the full command lines used to compile GHC executables,
set `verboseCommands` to:
```haskell
verboseCommand :: Predicate
verboseCommand = input "ghc/Main.hs"
```
Below are a few other examples:
```haskell
-- Print command lines for all Ghc Link invocations:
verboseCommand = builder (Ghc Link)
-- Print command lines when compiling files in package compiler using Gcc:
verboseCommand = builder (Gcc Compile) &&^ package compiler
-- Use patterns when matching files:
verboseCommand = output "//rts/sm/*" &&^ way threaded
-- Print all commands:
verboseCommand = return True
```
## Documentation
`Flavour`'s `ghcDocs :: Action DocTargets` field lets you
customize the "groups" of documentation targets that should
run when running `build docs` (or, transitively,
`build binary-dist`).
```haskell
type DocTargets = Set DocTarget
data DocTarget = Haddocks | SphinxHTML | SphinxPDFs | SphinxMan
```
By default, `ghcDocs` contains all of them and `build docs` would
therefore attempt to build all the haddocks, manuals and manpages.
If, for some reason (e.g no easy way to install `sphinx-build` or
`xelatex` on your system), you're just interested in building the
haddocks, you could define a custom flavour as follows:
```haskell
justHaddocksFlavour :: Flavour
justHaddocksFlavour = defaultFlavour
{ name = "default-haddocks"
, ghcDocs = Set.singleton Haddocks }
```
and then run `build --flavour=default-haddocks`. Alternatively,
you can use the `--docs` CLI flag to selectively disable some or
all of the documentation targets:
- `--docs=none`: don't build any docs
- `--docs=no-haddocks`: don't build haddocks
- `--docs=no-sphinx`: don't build any user manual or manpage
- `--docs=no-sphinx-html`: don't build HTML versions of manuals
- `--docs=no-sphinx-pdfs`: don't build PDF versions of manuals
- `--docs=no-sphinx-man`: don't build the manpage
You can pass several `--docs=...` flags, Hadrian will combine
their effects.
## Miscellaneous
Hadrian prints various progress info during the build. You can change the colours
used by default by overriding `buildProgressColour` and `successColour`:
```haskell
-- | Set colour for build progress messages (e.g. executing a build command).
buildProgressColour :: BuildProgressColour
buildProgressColour = mkBuildProgressColour (Dull Magenta)
-- | Set colour for success messages (e.g. a package is built successfully).
successColour :: SuccessColour
successColour = mkSuccessColour (Dull Green)
```
Your options are `Dull Colour`, `Vivid Colour`, or `Extended Code`. `Dull`
colours are the ANSI 8-bit colours, `Vivid` correspond to the 16-bit codes that
end with ";1", and `Extended` let's you enter a manual code for the 256 colour
set. E.g.
```
Dull Blue
Vivid Cyan
Extended "203"
```
|