Commit 3bac585e authored by Andrey Mokhov's avatar Andrey Mokhov

Update documentation

See #347, #440
parent a0ccea60
**Note:** This document is currently out-of-date and will be fixed after
[a major refactoring](https://github.com/snowleopard/hadrian/issues/347).
# User settings
You can customise Hadrian by copying the file `hadrian/src/UserSettings.hs` to
......@@ -11,11 +8,11 @@ them). Here we document currently supported settings.
## Build directory
Hadrian puts build results into `_build` directory by default, which is
specified by `buildRootPath`:
specified by `userBuildRoot`:
```haskell
-- | All build results are put into 'buildRootPath' directory.
buildRootPath :: FilePath
buildRootPath = "_build"
-- | All build results are put into the 'buildRoot' directory.
userBuildRoot :: BuildRoot
userBuildRoot = BuildRoot "_build"
```
## Build flavour
......@@ -23,44 +20,55 @@ buildRootPath = "_build"
Build _flavour_ is a collection of build settings that fully define a GHC build
(see `src/Flavour.hs`):
```haskell
data Flavour = Flavour
{ name :: String -- ^ Flavour name, to set from command line.
, args :: Args -- ^ Use these command line arguments.
, packages :: Packages -- ^ Build these packages.
, integerLibrary :: Package -- ^ Either 'integerGmp' or 'integerSimple'.
, libraryWays :: Ways -- ^ Build libraries these ways.
, rtsWays :: Ways -- ^ Build RTS these ways.
, splitObjects :: Predicate -- ^ Build split objects.
, buildHaddock :: Predicate -- ^ Build Haddock and documentation.
, dynamicGhcPrograms :: Bool -- ^ Build dynamic GHC programs.
, ghciWithDebugger :: Bool -- ^ Enable GHCi debugger.
, ghcProfiled :: Bool -- ^ Build profiled GHC.
, ghcDebugged :: Bool } -- ^ Build GHC with debug information.
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 split objects.
splitObjects :: Predicate,
-- | Build dynamic GHC programs.
dynamicGhcPrograms :: Bool,
-- | Enable GHCi debugger.
ghciWithDebugger :: Bool,
-- | Build profiled GHC.
ghcProfiled :: Bool,
-- | Build GHC with debug information.
ghcDebugged :: Bool }
```
Hadrian provides several
[built-in flavours](https://github.com/snowleopard/hadrian/blob/master/doc/flavours.md)
(`defaultFlavour`, `quickFlavour`, and
a few others), which can be activated from the command line, e.g. `--flavour=quick`.
Users can define new build flavours by adding them to `userFlavours` list:
Hadrian provides several built-in flavours (`defaultFlavour`, `quickFlavour`, 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
userFlavour :: Flavour
userFlavour = defaultFlavour { name = "user", ... } -- modify the default build flavour
-- | User defined build flavours. See 'userFlavour' as an example.
userFlavours :: [Flavour]
userFlavours = [userFlavour]
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. 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`. Import it as
`import {-# SOURCE #-} Settings.Default` to handle cyclic module dependencies.
`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.
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`:
......@@ -72,20 +80,16 @@ 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`. See also
`src/Package.hs`.
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 "//Evac_thr.c" ? append [ "-DPARALLEL_GC", "-Irts/sm" ]
, builder Ghc ? output "//Prelude.*" ? remove ["-Wall", "-fwarn-tabs"] ]
, package rts ? input "//Evac_thr.c" ? pure [ "-DPARALLEL_GC", "-Irts/sm" ] ]
```
The above example also demostrates the use of `append` for adding more than one
argument and `remove` for removing arguments that Hadrian uses by default. You
can match any combination of the `builder`, `stage`, `package`, `way`, `input`
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
......@@ -97,32 +101,35 @@ 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
userFlavour :: Flavour
userFlavour = defaultFlavour { name = "user", packages = defaultPackages <> userPackages }
userPackages :: Packages
userPackages = mconcat
[ stage0 ? append [base]
, stage1 ? remove [haskeline] ]
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 `userKnownPackages`:
by adding it to `userPackages`:
```haskell
userKnownPackages :: [Package]
userKnownPackages = [userPackage]
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
`userPackages` as otherwise it will not be built.
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
simpleFlavour :: Flavour
simpleFlavour = defaultFlavour { name = "simple", integerLibrary = integerSimple }
userFlavour :: Flavour
userFlavour = defaultFlavour { name = "user", integerLibrary = integerSimple }
```
## Build ways
......@@ -135,7 +142,7 @@ from the list of library ways:
noProfilingFlavour :: Flavour
noProfilingFlavour = defaultFlavour
{ name = "no-profiling"
, libraryWays = defaultLibraryWays <> remove [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
......@@ -148,11 +155,13 @@ 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 `verboseCommands` 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.: @verboseCommands = package ghcPrim@.
verboseCommands :: Predicate
verboseCommands = return False
-- | 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:
......@@ -178,26 +187,20 @@ verboseCommands = return True
## Miscellaneous
To change the default behaviour of Hadrian with respect to building split
objects and Haddock documentation, override `splitObjects` and `buildHaddock`
fields of the `Flavour` record, for example:
objects, override the `splitObjects` setting of the `Flavour` record:
```haskell
userFlavour :: Flavour
userFlavour = defaultFlavour { name = "user", splitObjects = return False, buildHaddock = return True }
userFlavour = defaultFlavour { name = "user", splitObjects = return False }
```
Hadrian prints various progress info during the build. You can customise how this
info is printed by overriding `putBuild` and `putSuccess` commands:
Hadrian prints various progress info during the build. You can change the colours
used by default by overriding `buildProgressColour` and `successColour`:
```haskell
-- | Customise build progress messages (e.g. executing a build command).
putBuild :: String -> Action ()
putBuild = putColoured Vivid White
-- | Set colour for build progress messages (e.g. executing a build command).
buildProgressColour :: BuildProgressColour
buildProgressColour = BuildProgressColour (Dull, Magenta)
-- | Customise build success messages (e.g. a package is built successfully).
putSuccess :: String -> Action ()
putSuccess = putColoured Vivid Green
-- | Set colour for success messages (e.g. a package is built successfully).
successColour :: SuccessColour
successColour = SuccessColour (Dull, Green)
```
You can tune colours for your favourite terminal and also change the verbosity
level, e.g. by setting `putSuccess = putLoud`, which will hide success messages
unless Hadrian is called with `--verbose` flag.
......@@ -2,6 +2,7 @@ module Flavour (Flavour (..)) where
import Expression
-- Please update doc/{flavours.md, user-settings.md} when changing this file.
-- | 'Flavour' is a collection of build settings that fully define a GHC build.
-- Note the following type semantics:
-- * @Bool@: a plain Boolean flag whose value is known at compile time.
......@@ -9,7 +10,7 @@ import Expression
-- * @Predicate@: a flag whose value can depend on the build environment and
-- on the current build target.
data Flavour = Flavour {
-- | Flavour name, to set from command line.
-- | Flavour name, to select this flavour from command line.
name :: String,
-- | Use these command line arguments.
args :: Args,
......
......@@ -12,16 +12,23 @@ import System.Console.ANSI
import Flavour
import Expression
import {-# SOURCE #-} Settings.Default
-- See doc/user-settings.md for instructions.
-- Please update doc/user-settings.md when committing changes to this file.
-- | All build results are put into the 'buildRoot' directory.
userBuildRoot :: BuildRoot
userBuildRoot = BuildRoot "_build"
-- | User defined build flavours. See 'defaultFlavour' as an example.
-- | User defined build flavours. See 'userFlavour' as an example.
userFlavours :: [Flavour]
userFlavours = []
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.
-- | Add user defined packages. Note, this only lets Hadrian know about the
-- existence of a new package; to actually build it you need to create a new
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment