Hadrian: introduce an easy way for users to build with -split-sections
authorAlp Mestanogullari <alpmestan@gmail.com>
Fri, 15 Mar 2019 20:35:59 +0000 (21:35 +0100)
committerMarge Bot <ben+marge-bot@smart-cactus.org>
Wed, 27 Mar 2019 11:20:05 +0000 (07:20 -0400)
Any user can now trivially build any number of Haskell packages with
`-split-sections` by using `splitSections`/`splitSectionsIf` on any
existing or new flavour:

    -- build all packages but the ghc library with -split-sections
    splitSections :: Flavour -> Flavour

    -- build all packages that satisfy the given predicate
    -- with --split-sections
    splitSectionsIf :: (Package -> Bool) -> Flavour -> Flavour

See the new section in `doc/user-settings.md`.

hadrian/doc/user-settings.md
hadrian/src/Flavour.hs

index d0531a3..b6b4452 100644 (file)
@@ -271,6 +271,32 @@ all of the documentation targets:
 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
@@ -295,3 +321,5 @@ Dull Blue
 Vivid Cyan
 Extended "203"
 ```
+
+[split-sections]: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/phases.html#ghc-flag--split-sections
index 06407e7..230272e 100644 (file)
@@ -1,10 +1,12 @@
 module Flavour
   ( Flavour (..), werror
   , DocTargets, DocTarget(..)
+  , splitSections, splitSectionsIf
   ) where
 
 import Expression
 import Data.Set (Set)
+import Packages
 
 -- 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.
@@ -63,3 +65,26 @@ data DocTarget = Haddocks | SphinxHTML | SphinxPDFs | SphinxMan
 -- It mimics the CI settings so is useful to turn on when developing.
 werror :: Flavour -> Flavour
 werror fl = fl { args = args fl <> (builder Ghc ? notStage0 ? arg "-Werror") }
+
+-- | Transform the input 'Flavour' so as to build with
+--   @-split-sections@ whenever appropriate. You can
+--   select which package gets built with split sections
+--   by passing a suitable predicate. If the predicate holds
+--   for a given package, then @split-sections@ is used when
+--   building it. If the given flavour doesn't build
+--   anything in a @dyn@-enabled way, then 'splitSections' is a no-op.
+splitSectionsIf :: (Package -> Bool) -> Flavour -> Flavour
+splitSectionsIf pkgPredicate fl = fl { args = args fl <> splitSectionsArg }
+
+  where splitSectionsArg = do
+          way <- getWay
+          pkg <- getPackage
+          (Dynamic `wayUnit` way) ? pkgPredicate pkg ?
+            builder (Ghc CompileHs) ? arg "-split-sections"
+
+-- | Like 'splitSectionsIf', but with a fixed predicate: use
+--   split sections for all packages but the GHC library.
+splitSections :: Flavour -> Flavour
+splitSections = splitSectionsIf (/=ghc)
+-- Disable section splitting for the GHC library. It takes too long and
+-- there is little benefit.