summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArtem Pyanykh <artempyanykh@gmail.com>2019-09-11 21:12:32 +0100
committerMarge Bot <ben+marge-bot@smart-cactus.org>2019-09-23 17:54:04 -0400
commitd0c2f3a2b6ec2d3ee2b9f017eb52c72cf6187d6f (patch)
tree8d1499509979fe3fc2363188664fb8168bdd013d
parent2778929466dafefd55a0673625f4520a234df986 (diff)
downloadhaskell-d0c2f3a2b6ec2d3ee2b9f017eb52c72cf6187d6f.tar.gz
[hadrian] Rebuild programs on dynamicGhcPrograms/ghcProfiled change
Currently, if you change these ^ flavour parameters, rebuilding is not triggered, since `programContext` doesn't set up a dependency on those values. Exposing these values via an oracle does set the dependency and properly triggers a rebuild of binaries. Several attempts to factor out these actions ended up in cyclic dependency here or there. I'm not absolutely happy with this variant either, but at least it works. ==== Issue repro: In UserSettings.hs: ``` dbgDynamic = defaultFlavour { name = "dbg-dynamic" , dynamicGhcPrograms = pure True, ... } dbgStatic = defaultFlavour { name = "dbg-static" , dynamicGhcPrograms = pure False ... } ``` Then in console: ``` $ hadrian/build.sh -j --flavour=dbg-dynamic ... does the build $ hadrian/build.sh -j --flavour=dbg-static ... does nothing, considers binaries up to date ```
-rw-r--r--hadrian/hadrian.cabal2
-rw-r--r--hadrian/src/Oracles/Flavour.hs33
-rw-r--r--hadrian/src/Oracles/TestSettings.hs2
-rw-r--r--hadrian/src/Rules.hs4
-rw-r--r--hadrian/src/Rules/BinaryDist.hs1
-rw-r--r--hadrian/src/Rules/Program.hs1
-rw-r--r--hadrian/src/Rules/Test.hs1
-rwxr-xr-xhadrian/src/Settings.hs19
-rw-r--r--hadrian/src/Settings/Builders/Make.hs1
-rw-r--r--hadrian/src/Settings/Program.hs24
10 files changed, 68 insertions, 20 deletions
diff --git a/hadrian/hadrian.cabal b/hadrian/hadrian.cabal
index 6037a21849..02c64bc9e7 100644
--- a/hadrian/hadrian.cabal
+++ b/hadrian/hadrian.cabal
@@ -48,6 +48,7 @@ executable hadrian
, Hadrian.Target
, Hadrian.Utilities
, Oracles.Flag
+ , Oracles.Flavour
, Oracles.Setting
, Oracles.ModuleFiles
, Oracles.TestSettings
@@ -102,6 +103,7 @@ executable hadrian
, Settings.Flavours.GhcInGhci
, Settings.Packages
, Settings.Parser
+ , Settings.Program
, Settings.Warnings
, Stage
, Target
diff --git a/hadrian/src/Oracles/Flavour.hs b/hadrian/src/Oracles/Flavour.hs
new file mode 100644
index 0000000000..88e9c89757
--- /dev/null
+++ b/hadrian/src/Oracles/Flavour.hs
@@ -0,0 +1,33 @@
+{-# LANGUAGE ConstraintKinds #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE TypeFamilies #-}
+
+module Oracles.Flavour
+ ( oracles
+ , askDynGhcPrograms
+ , askGhcProfiled
+ ) where
+
+import Base
+import Flavour
+import Settings (flavour)
+
+newtype DynGhcPrograms =
+ DynGhcPrograms () deriving (Show, Typeable, Eq, Hashable, Binary, NFData)
+type instance RuleResult DynGhcPrograms = Bool
+
+newtype GhcProfiled =
+ GhcProfiled () deriving (Show, Typeable, Eq, Hashable, Binary, NFData)
+type instance RuleResult GhcProfiled = Bool
+
+oracles :: Rules ()
+oracles = do
+ void $ addOracle $ \(DynGhcPrograms _) -> dynamicGhcPrograms =<< flavour
+ void $ addOracle $ \(GhcProfiled _) -> ghcProfiled <$> flavour
+
+askDynGhcPrograms :: Action Bool
+askDynGhcPrograms = askOracle $ DynGhcPrograms ()
+
+askGhcProfiled :: Action Bool
+askGhcProfiled = askOracle $ GhcProfiled ()
diff --git a/hadrian/src/Oracles/TestSettings.hs b/hadrian/src/Oracles/TestSettings.hs
index 9d93e10cf4..ba89e00beb 100644
--- a/hadrian/src/Oracles/TestSettings.hs
+++ b/hadrian/src/Oracles/TestSettings.hs
@@ -10,8 +10,8 @@ module Oracles.TestSettings
import Base
import Hadrian.Oracles.TextFile
import Oracles.Setting (topDirectory, setting, Setting(..))
-import Settings (programContext)
import Packages
+import Settings.Program (programContext)
testConfigFile :: Action FilePath
testConfigFile = buildRoot <&> (-/- "test/ghcconfig")
diff --git a/hadrian/src/Rules.hs b/hadrian/src/Rules.hs
index 5b2682390a..e72623d4ce 100644
--- a/hadrian/src/Rules.hs
+++ b/hadrian/src/Rules.hs
@@ -8,6 +8,7 @@ import qualified Hadrian.Oracles.Path
import qualified Hadrian.Oracles.TextFile
import Expression
+import qualified Oracles.Flavour
import qualified Oracles.ModuleFiles
import Packages
import qualified Rules.BinaryDist
@@ -24,10 +25,10 @@ import qualified Rules.Register
import qualified Rules.Rts
import qualified Rules.SimpleTargets
import Settings
+import Settings.Program (programContext)
import Target
import UserSettings
-
-- | @tool-args@ is used by tooling in order to get the arguments necessary
-- to set up a GHC API session which can compile modules from GHC. When
-- run, the target prints out the arguments that would be passed to @ghc@
@@ -176,4 +177,5 @@ oracleRules = do
Hadrian.Oracles.DirectoryContents.directoryContentsOracle
Hadrian.Oracles.Path.pathOracle
Hadrian.Oracles.TextFile.textFileOracle
+ Oracles.Flavour.oracles
Oracles.ModuleFiles.moduleFilesOracle
diff --git a/hadrian/src/Rules/BinaryDist.hs b/hadrian/src/Rules/BinaryDist.hs
index 11301a0372..fb7fa47c84 100644
--- a/hadrian/src/Rules/BinaryDist.hs
+++ b/hadrian/src/Rules/BinaryDist.hs
@@ -7,6 +7,7 @@ import Expression
import Oracles.Setting
import Packages
import Settings
+import Settings.Program (programContext)
import Target
import Utilities
diff --git a/hadrian/src/Rules/Program.hs b/hadrian/src/Rules/Program.hs
index b5dde25624..6273f3da4d 100644
--- a/hadrian/src/Rules/Program.hs
+++ b/hadrian/src/Rules/Program.hs
@@ -12,6 +12,7 @@ import Oracles.Setting (topDirectory)
import Packages
import Settings
import Settings.Default
+import Settings.Program (programContext)
import Target
import Utilities
import Rules.Library
diff --git a/hadrian/src/Rules/Test.hs b/hadrian/src/Rules/Test.hs
index 5dea40a48b..84374ff492 100644
--- a/hadrian/src/Rules/Test.hs
+++ b/hadrian/src/Rules/Test.hs
@@ -12,6 +12,7 @@ import Packages
import Settings
import Settings.Default
import Settings.Builders.RunTest
+import Settings.Program (programContext)
import Target
import Utilities
diff --git a/hadrian/src/Settings.hs b/hadrian/src/Settings.hs
index 0548bccfae..ba0cff770a 100755
--- a/hadrian/src/Settings.hs
+++ b/hadrian/src/Settings.hs
@@ -1,8 +1,7 @@
module Settings (
getArgs, getLibraryWays, getRtsWays, flavour, knownPackages,
findPackageByName, unsafeFindPackageByName, unsafeFindPackageByPath,
- isLibrary, stagePackages, programContext, getIntegerPackage,
- completeSetting
+ isLibrary, stagePackages, getIntegerPackage, completeSetting
) where
import CommandLine
@@ -68,22 +67,6 @@ flavour = do
getIntegerPackage :: Expr Package
getIntegerPackage = expr (integerLibrary =<< flavour)
--- TODO: there is duplication and inconsistency between this and
--- Rules.Program.getProgramContexts. There should only be one way to get a
--- context / contexts for a given stage and package.
-programContext :: Stage -> Package -> Action Context
-programContext stage pkg = do
- profiled <- ghcProfiled <$> flavour
- dynGhcProgs <- dynamicGhcPrograms =<< flavour
- return $ Context stage pkg (wayFor profiled dynGhcProgs)
-
- where wayFor prof dyn
- | prof && dyn =
- error "programContext: profiling+dynamic not supported"
- | pkg == ghc && prof && stage > Stage0 = profiling
- | dyn && stage > Stage0 = dynamic
- | otherwise = vanilla
-
-- TODO: switch to Set Package as the order of packages should not matter?
-- Otherwise we have to keep remembering to sort packages from time to time.
knownPackages :: [Package]
diff --git a/hadrian/src/Settings/Builders/Make.hs b/hadrian/src/Settings/Builders/Make.hs
index 56bb8e35fb..431c2cb22e 100644
--- a/hadrian/src/Settings/Builders/Make.hs
+++ b/hadrian/src/Settings/Builders/Make.hs
@@ -4,6 +4,7 @@ import Oracles.Setting
import Packages
import Rules.Gmp
import Settings.Builders.Common
+import Settings.Program (programContext)
import CommandLine
makeBuilderArgs :: Args
diff --git a/hadrian/src/Settings/Program.hs b/hadrian/src/Settings/Program.hs
new file mode 100644
index 0000000000..d98b1a9327
--- /dev/null
+++ b/hadrian/src/Settings/Program.hs
@@ -0,0 +1,24 @@
+module Settings.Program
+ ( programContext
+ ) where
+
+import Base
+import Context
+import Oracles.Flavour
+import Packages
+
+-- TODO: there is duplication and inconsistency between this and
+-- Rules.Program.getProgramContexts. There should only be one way to
+-- get a context/contexts for a given stage and package.
+programContext :: Stage -> Package -> Action Context
+programContext stage pkg = do
+ profiled <- askGhcProfiled
+ dynGhcProgs <- askDynGhcPrograms --dynamicGhcPrograms =<< flavour
+ return $ Context stage pkg (wayFor profiled dynGhcProgs)
+
+ where wayFor prof dyn
+ | prof && dyn =
+ error "programContext: profiling+dynamic not supported"
+ | pkg == ghc && prof && stage > Stage0 = profiling
+ | dyn && stage > Stage0 = dynamic
+ | otherwise = vanilla