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 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433
|
# Settings
You can customise Hadrian in two ways:
- By selecting a flavour, flavour transformers and using
key-value settings, either in the command line
or by modifying the `hadrian.settings` file in the build directory.
- By overriding the default build settings in the source code,
by copying the file `hadrian/src/UserSettings.hs` to `hadrian/UserSettings.hs`
and making modifications (if you don't copy the file, your changes will be tracked by `git`
and you can accidentally commit them).
## Build flavours
A 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],
-- | Bignum backend: 'native', 'gmp', 'ffi', etc.
bignumBackend :: String,
-- | Check selected bignum backend against native backend
bignumCheck :: Bool,
-- | Build libraries these ways.
libraryWays :: Ways,
-- | Build RTS these ways.
rtsWays :: Ways,
-- | Build dynamic GHC programs.
dynamicGhcPrograms :: Action Bool,
-- | Enable GHCi debugger.
ghciWithDebugger :: Stage -- ^ stage of the /built/ compiler
-> Bool,
-- | Build profiled GHC.
ghcProfiled :: Stage -- ^ stage of the /built/ compiler
-> Bool,
-- | Build GHC with the debug RTS.
ghcDebugged :: Stage -- ^ stage of the /built/ compiler
-> Bool,
-- | Build GHC with debug assertions (-DDEBUG).
ghcDebugAssertions :: Stage -- ^ stage of the /built/ compiler
-> Bool,
-- | Build the GHC executable against the threaded runtime system.
ghcThreaded :: Stage -- ^ stage of the /built/ compiler
-> 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`.
## Flavour transformers
Flavours can be customised using [flavour transformers](flavours.md#flavour-transformers).
For example, 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` flavour transformer
can be used to easily modify a flavour to turn this setting on:
```
hadrian/build --flavour=validate+werror
```
## `key = value` and `key += value` style settings
One can supply settings from the command line or a
`<build root>/hadrian.settings` file. Hadrian currently supports
the following "families" of settings:
- `{stage0, ..., stage3, *}.(<package name> or *).ghc.{c, hs, link, deps, toolargs, *}.opts`
- `{stage0, ..., stage3, *}.(<package name> or *).cc.{c, deps, *}.opts`
- `{stage0, ..., stage3, *}.(<package name> or *).cabal.configure.opts`
- `{stage0, ..., stage3, *}.(<package name> or *).hsc2hs.run.opts`
For example, putting the following in a file at `_build/hadrian.settings`:
``` make
stage1.ghc-bin.ghc.link.opts += -debug
*.base.ghc.*.opts += -v3
```
and running hadrian with the default build root (`_build`), would respectively
link the stage 2 GHC executable (using the stage 1 GHC) with the `-debug`
flag and use `-v3` on all GHC commands used to build anything related to
`base`, whatever the stage.
We could equivalently specify those settings on the command-line:
``` sh
$ hadrian/build "stage1.ghc-bin.ghc.link.opts += -eventlog" \
"*.base.ghc.*.opts += -v3"
```
or specify some in `hadrian.settings` and some on the command-line.
Here is an overview of the supported settings and how you can figure out
the right names for them:
- the stage slot, which comes first, can be filled with any of `stage0`,
`stage1`, `stage2`, `stage3` or `*`; any value but `*` will restrict the
setting update to targets built during the given stage, while `*` is taken
to mean "for any stage". For instance, the above example will affect
the linking of the `_build/stage1/bin/ghc` executable.
- the package slot, which comes second, can be filled with any package name
that Hadrian knows about (all packages that are part of a GHC checkout),
or `*`, to respectively mean that the builder options are going to be updated
only when building the given package, or that the said options should be used
when building all known packages, if the Hadrian command ever gets them to be
built;
- the remaining slots specify the builder and how it was invoked,
* `ghc` refers to GHC commands; the final slot refers to how GHC is invoked:
* `c.opts` for commands that build C files with GHC
* `hs.opts` for commands that compile Haskell modules with GHC
* `link.opts` for GHC linking command
* `deps.opts` for commands that figure out dependencies between Haskell modules
(with `ghc -M`)
* `toolargs.opts` for GHC commands that are used to generate the right ghci
argument for `hadrian/ghci` to work
* `cc` refers to C compiler commands
* `cxx` refers to C++ compiler commands
* `c.opts` for commands that call the C compiler on some C files
* `deps.opts` for commands that call the C compiler for figuring out
dependencies between C files
* `cabal.configure.opts` refers to Cabal configure command line. Note that
package flags can be given by adding `--flags=...` arguments.
* `hsc2hs.run.opts` allows passing options to `Hsc2Hs` invocations.
* `runtest.opts` defines extra arguments passed to `runtest.py` when
invoked via the `hadrian test` target.
- using a wildcard (`*`) ranges over all possible values for a given "slot";
- `=` entirely overrides the arguments for a given builder in a given context,
with the value specified on the right hand side of `=`, while `+=` merely
extends the arguments that are to be emitted in the said context, with
the values supplied on the right hand side of `+=`.
See `Note [Hadrian settings]` in `hadrian/src/Settings.hs` for explanations
about the implementation and how the set of supported settings can be
extended.
## Directly modifying Hadrian configuration
If the existing configuration options aren't enough for your needs,
you can directly add new configurations to Hadrian.
### Defining new flavours
Users can define new build flavours by adding them to the `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`.
### Passing command line arguments to builders
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/Packages.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, but not absolute path
prefixes, and `*` matches an entire path component, excluding any separators.
#### Linking GHC against the debugged RTS
What was previously achieved by having `GhcDebugged=YES` in `mk/build.mk` can
be done by defining a custom flavour in the user settings file, one that
sets the `ghcDebugged` field of `Flavour` to `True`, e.g:
``` haskell
quickDebug :: Flavour
quickDebug = quickFlavour { name = "dbg", ghcDebugged = True }
```
Running `build --flavour=dbg` will build a `quick`-flavoured GHC and link
GHC, iserv, iserv-proxy and remote-iserv against the debugged RTS, by passing
`-debug` to the commands that link those executables.
### 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 Bignum backend to use when buidling GHC using the
`bignumBackend` setting of the build flavour. Possible values are: `gmp`
(default), `native` or `ffi`.
```haskell
userFlavour :: Flavour
userFlavour = defaultFlavour { name = "user", bignumBackend = "native" }
```
#### 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 }
```
### 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.
### Split sections
You can build all or just a few packages with
[`-split-sections`][split-sections] by tweaking an existing
flavour (whichever matches your needs) using
`splitSections` or `splitSectionsIf`:
``` haskell
splitSections :: Flavour -> Flavour
splitSectionsIf :: (Package -> Bool) -> Flavour -> Flavour
```
For example, you can easily start with the `quick` flavour and
additionally build all Haskell packages with `-split-sections` by defining a new
flavour as
`(splitSectionsIf (const True) quickFlavour) { name = "quick-split" }`.
You can then start a build with this flavour with `build --flavour=quick-split`.
Changing `(const True)` to `(== base)` would only build `base` with
`-split-sections`, not all Haskell packages as with `quick-split` above.
`splitSections` is simply `splitSectionsIf` applied to the predicate
`(/=ghc)`, i.e it builds all Haskell packages but the `ghc`
library with `-split-sections` (it is usually not worth using that
option with the `ghc` library).
### 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"
```
### Tab completion
Hadrian supports tab-completion for the key-value settings. This is implemented
in `Rules.SimpleTargets.completionRule`, by exporting an `autocomplete` target
that takes an (optional) argument, `--complete-setting=<some string>`, and
prints on stdout all the setting keys that have the given string as a prefix.
There is a `hadrian/completion.sh` script that makes use of this rule to
install Bash completions for `hadrian/build` and `hadrian/build-cabal`.
You can try it out by doing:
``` sh
$ source hadrian/completion.sh
$ hadrian/build <TAB>
$ hadrian/build stage1.ba<TAB>
$ hadrian/build "stage1.base.ghc.<TAB>
$ hadrian/build "*.*.ghc.*.opts += -v3" "stage0.ghc-bin.ghc.lin<TAB>
```
[split-sections]: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/phases.html#ghc-flag--split-sections
|