summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2021-11-17 10:17:07 -0500
committerBen Gamari <ben@smart-cactus.org>2021-11-17 12:25:52 -0500
commitc236da02bde8f12b07c3f7f9056d1bdd806f4748 (patch)
tree2508ba51804661b31652bcafd89ba9d24f938dab
parentcc635da167fdec2dead0603b0026cb841f0aa645 (diff)
downloadhaskell-wip/hadrian-persistent-flavour.tar.gz
hadrian: Persist the used flavour name in the build rootwip/hadrian-persistent-flavour
This executes the idea proposed in #20650, teaching Hadrian to persist the flavour used to build a build root. This both makes use of multiple build roots more ergonomic (as the user no longer needs to repeat themselves) and avoids a tiresome foot-gun (forgetting to specify a flavour, often wholly invalidating a build root). Closes #20650.
-rw-r--r--hadrian/doc/flavours.md7
-rw-r--r--hadrian/src/Main.hs2
-rw-r--r--hadrian/src/Rules.hs1
-rwxr-xr-xhadrian/src/Settings.hs50
4 files changed, 55 insertions, 5 deletions
diff --git a/hadrian/doc/flavours.md b/hadrian/doc/flavours.md
index b088b8ab92..6118272aba 100644
--- a/hadrian/doc/flavours.md
+++ b/hadrian/doc/flavours.md
@@ -3,7 +3,12 @@
Hadrian supports a few predefined _build flavours_, i.e. collections of build
settings that fully define a GHC build (see `src/Flavour.hs`). Users can add their
own build flavours if need be, as described
-[here](https://gitlab.haskell.org/ghc/ghc/blob/master/hadrian/doc/user-settings.md#build-flavour).
+[here](https://gitlab.haskell.org/ghc/ghc/blob/master/hadrian/doc/user-settings.md#build-flavour) or modify existing flavours using the flavour transformers notion seem below.
+
+The flavour to be used for a build root can be specified on the command-line
+via the `--flavour` flag. Moreover, this flavour name is saved in the build
+root; future invocations of Hadrian without a `--flavour` flag will default to
+the last-used flavour.
## Arguments
diff --git a/hadrian/src/Main.hs b/hadrian/src/Main.hs
index d2e0ace795..5e27d88846 100644
--- a/hadrian/src/Main.hs
+++ b/hadrian/src/Main.hs
@@ -116,7 +116,7 @@ main = do
Environment.setupEnvironment
return . Just $ (shake_opts, if null targets'
then rules
- else want targets' >> withoutActions rules)
+ else want targets' >> rules)
handleShakeException :: IORef ShakeOptions -> IO a -> IO a
handleShakeException shake_opts_var shake_run = do
diff --git a/hadrian/src/Rules.hs b/hadrian/src/Rules.hs
index 67646a8689..f427da5be5 100644
--- a/hadrian/src/Rules.hs
+++ b/hadrian/src/Rules.hs
@@ -128,6 +128,7 @@ packageRules = do
buildRules :: Rules ()
buildRules = do
+ Settings.flavourFileRules
Rules.BinaryDist.bindistRules
Rules.Generate.copyRules
Rules.Generate.generateRules
diff --git a/hadrian/src/Settings.hs b/hadrian/src/Settings.hs
index 50ef988036..17f2f41906 100755
--- a/hadrian/src/Settings.hs
+++ b/hadrian/src/Settings.hs
@@ -3,7 +3,8 @@
module Settings (
getArgs, getLibraryWays, getRtsWays, flavour, knownPackages,
findPackageByName, unsafeFindPackageByName, unsafeFindPackageByPath,
- isLibrary, stagePackages, getBignumBackend, getBignumCheck, completeSetting
+ isLibrary, stagePackages, getBignumBackend, getBignumCheck, completeSetting,
+ flavourFileRules
) where
import CommandLine
@@ -58,6 +59,49 @@ hadrianFlavours =
, ghcInGhciFlavour, validateFlavour, slowValidateFlavour
]
+{-
+Note [Persisting the flavour]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+For a long time Hadrian relied on UserSettings.hs for all configuration.
+However, this approach to configuration is both inconvenient and interacts
+poorly with multiple build roots. For this reason we introduced flavour
+transformers, making it easier to modify the flavour from the command-line.
+However, passing the flavour on the command-line introduces another problem:
+the user must consistently pass the same --flavour flag to all Hadrian
+invocations on a particular build root. Forgetting even once can result in a
+full rebuild of the tree.
+
+To eliminate the inconvenience of needing to always pass --flavour arguments we
+persist the flavour name used to build a particular build root in the build
+root itself (specifically, in `<build root>/flavour`). We refer to this file
+when looking up the active flavour, defaulting to it if the user does not
+specify a flavour name explicitly.
+-}
+
+flavourFileRules :: Rules ()
+flavourFileRules = do
+ root <- buildRootRules
+ root -/- "flavour" %> \out -> do
+ flavourName <- getFlavourName
+ writeFile' out flavourName
+
+ -- Ensure that the persistent flavour file is always updated.
+ want [root -/- "flavour"]
+
+-- | Lookup the requested flavour name, referring to the persistent flavour
+-- file saved from the previous Hadrian execution if not specified.
+getFlavourName :: Action String
+getFlavourName = do
+ root <- buildRoot
+ let flavourFile = root -/- "flavour"
+ mbFlavourName <- cmdFlavour
+ case mbFlavourName of
+ Nothing -> do exists <- doesFileExist flavourFile
+ if exists
+ then liftIO $ readFile flavourFile
+ else return userDefaultFlavour
+ Just nm -> return nm
+
-- | This action looks up a flavour with the name given on the
-- command line with @--flavour@, defaulting to 'userDefaultFlavour'
-- when no explicit @--flavour@ is passed. It then applies any
@@ -66,7 +110,7 @@ hadrianFlavours =
-- syntax. See Note [Hadrian settings] at the bottom of this file.
flavour :: Action Flavour
flavour = do
- flavourName <- fromMaybe userDefaultFlavour <$> cmdFlavour
+ flavourName <- getFlavourName
kvs <- userSetting ([] :: [KeyVal])
let flavours = hadrianFlavours ++ userFlavours
(settingErrs, tweak) = applySettings kvs
@@ -96,4 +140,4 @@ unsafeFindPackageByName name = fromMaybe (error msg) $ findPackageByName name
unsafeFindPackageByPath :: FilePath -> Package
unsafeFindPackageByPath path = err $ find (\pkg -> pkgPath pkg == path) knownPackages
where
- err = fromMaybe $ error ("findPackageByPath: No package for path " ++ path) \ No newline at end of file
+ err = fromMaybe $ error ("findPackageByPath: No package for path " ++ path)