[Git][ghc/ghc][wip/hadrian-cross-stage2] Split up system.config into host/target config files

Matthew Pickering (@mpickering) gitlab at gitlab.haskell.org
Fri Mar 8 09:56:49 UTC 2024



Matthew Pickering pushed to branch wip/hadrian-cross-stage2 at Glasgow Haskell Compiler / GHC


Commits:
04bc9786 by Matthew Pickering at 2024-03-08T09:56:31+00:00
Split up system.config into host/target config files

There were a number of settings which were not applied per-stage, for
example if you specified `--ffi-include-dir` then that was applied to
both host and target. Now this will just be passed when building the
crosscompiler.

The solution for now is to separate these two files into host/target and
the host file contains very bare-bones . There isn't currently a way to
specify with configure anything in the host file, so if you are building
a cross-compiler and you need to do that, you have to modify the file
yourself.

- - - - -


23 changed files:

- configure.ac
- hadrian/README.md
- + hadrian/cfg/system.config.host.in
- hadrian/cfg/system.config.in
- + hadrian/cfg/system.config.target.in
- hadrian/src/Base.hs
- hadrian/src/Builder.hs
- hadrian/src/Expression.hs
- hadrian/src/Hadrian/Oracles/TextFile.hs
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Oracles/TestSettings.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Rules/Libffi.hs
- hadrian/src/Rules/Rts.hs
- hadrian/src/Settings/Builders/Cabal.hs
- hadrian/src/Settings/Builders/Common.hs
- hadrian/src/Settings/Builders/Ghc.hs
- hadrian/src/Settings/Builders/Hsc2Hs.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Packages.hs
- hadrian/src/Settings/Warnings.hs


Changes:

=====================================
configure.ac
=====================================
@@ -976,6 +976,8 @@ FIND_GHC_TOOLCHAIN([hadrian/cfg])
 AC_CONFIG_FILES(
 [ mk/project.mk
   hadrian/cfg/system.config
+  hadrian/cfg/system.config.host
+  hadrian/cfg/system.config.target
   hadrian/ghci-cabal
   hadrian/ghci-multi-cabal
   hadrian/ghci-stack


=====================================
hadrian/README.md
=====================================
@@ -327,6 +327,16 @@ workflow, for now.
 
 Note: On windows you need to use the `reloc-binary-dist` target.
 
+#### Cross Compiling
+
+If you are cross compiling then all the settings specified to ./configure are
+for the target system. For example, if you specify `--with-ffi-includes` then
+this is specifically for the target.
+
+If your host system needs additional configuration in order to build a stage1 compiler,
+then at the moment you need to manually edit the "cfg/system.config.host.in" file to
+specify these options in the right place.
+
 #### Relocatable Binary Distribution
 
 If you require a relocatable binary distribution (for example on Windows), then you


=====================================
hadrian/cfg/system.config.host.in
=====================================
@@ -0,0 +1,77 @@
+# This file is processed by the configure script.
+# See hadrian/src/UserSettings.hs for user-defined settings.
+#===========================================================
+
+# Paths to builders:
+#===================
+
+# Information about builders:
+#============================
+
+cc-llvm-backend           = NO
+
+
+# Information about build, host and target systems:
+#==================================================
+
+dynamic-extension     = @soext_host@
+
+bootstrap-threaded-rts = YES
+
+# Settings:
+#==========
+
+# We are in the process of moving the settings file from being entirely
+# generated by configure, to generated being by the build system. Many of these
+# might become redundant.
+# See Note [tooldir: How GHC finds mingw on Windows]
+
+settings-otool-command = otool
+settings-install_name_tool-command = install_name_tool
+settings-llc-command = llc
+settings-opt-command = opt
+settings-llvm-as-command = clang
+settings-use-distro-mingw = NO
+
+target-has-libm = YES
+
+# Include and library directories:
+#=================================
+
+curses-lib-dir     =
+curses-include-dir =
+
+iconv-include-dir =
+iconv-lib-dir     =
+
+intree-gmp              = NO
+gmp-framework-preferred = NO
+gmp-include-dir         =
+gmp-lib-dir             =
+
+use-system-ffi    = NO
+ffi-include-dir   =
+ffi-lib-dir       =
+
+libdw-include-dir   =
+libdw-lib-dir       =
+
+libnuma-include-dir   =
+libnuma-lib-dir       =
+
+libzstd-include-dir   =
+libzstd-lib-dir       =
+
+# Optional Dependencies:
+#=======================
+
+use-lib-dw        = NO
+use-lib-zstd      = NO
+static-lib-zstd   = NO
+use-lib-numa      = NO
+use-lib-m         = YES
+use-lib-rt        = YES
+use-lib-dl        = YES
+use-lib-bfd       = NO
+use-lib-pthread   = NO
+need-libatomic    = NO


=====================================
hadrian/cfg/system.config.in
=====================================
@@ -32,8 +32,6 @@ python         = @PythonCmd@
 # Information about builders:
 #============================
 
-cc-llvm-backend           = @CcLlvmBackend@
-
 llvm-min-version          = @LlvmMinVersion@
 llvm-max-version          = @LlvmMaxVersion@
 
@@ -54,8 +52,6 @@ target-platform-full  = @TargetPlatformFull@
 
 cross-compiling       = @CrossCompiling@
 
-dynamic-extension     = @soext_target@
-
 ghc-version           = @GhcVersion@
 ghc-major-version     = @GhcMajVersion@
 ghc-minor-version     = @GhcMinVersion@
@@ -72,60 +68,3 @@ project-patch-level1   = @ProjectPatchLevel1@
 project-patch-level2   = @ProjectPatchLevel2@
 project-git-commit-id  = @ProjectGitCommitId@
 
-# Settings:
-#==========
-
-# We are in the process of moving the settings file from being entirely
-# generated by configure, to generated being by the build system. Many of these
-# might become redundant.
-# See Note [tooldir: How GHC finds mingw on Windows]
-
-settings-otool-command = @SettingsOtoolCommand@
-settings-install_name_tool-command = @SettingsInstallNameToolCommand@
-settings-llc-command = @SettingsLlcCommand@
-settings-opt-command = @SettingsOptCommand@
-settings-llvm-as-command = @SettingsLlvmAsCommand@
-settings-use-distro-mingw = @SettingsUseDistroMINGW@
-
-target-has-libm = @TargetHasLibm@
-
-# Include and library directories:
-#=================================
-
-curses-lib-dir     = @CURSES_LIB_DIRS@
-curses-include-dir = @CURSES_INCLUDE_DIRS@
-
-iconv-include-dir = @ICONV_INCLUDE_DIRS@
-iconv-lib-dir     = @ICONV_LIB_DIRS@
-
-intree-gmp              = @GMP_FORCE_INTREE@
-gmp-framework-preferred = @GMP_PREFER_FRAMEWORK@
-gmp-include-dir         = @GMP_INCLUDE_DIRS@
-gmp-lib-dir             = @GMP_LIB_DIRS@
-
-use-system-ffi    = @UseSystemLibFFI@
-ffi-include-dir   = @FFIIncludeDir@
-ffi-lib-dir       = @FFILibDir@
-
-libdw-include-dir   = @LibdwIncludeDir@
-libdw-lib-dir       = @LibdwLibDir@
-
-libnuma-include-dir   = @LibNumaIncludeDir@
-libnuma-lib-dir       = @LibNumaLibDir@
-
-libzstd-include-dir   = @LibZstdIncludeDir@
-libzstd-lib-dir       = @LibZstdLibDir@
-
-# Optional Dependencies:
-#=======================
-
-use-lib-dw        = @UseLibdw@
-use-lib-zstd      = @UseLibZstd@
-static-lib-zstd   = @UseStaticLibZstd@
-use-lib-numa      = @UseLibNuma@
-use-lib-m         = @UseLibm@
-use-lib-rt        = @UseLibrt@
-use-lib-dl        = @UseLibdl@
-use-lib-bfd       = @UseLibbfd@
-use-lib-pthread   = @UseLibpthread@
-need-libatomic    = @NeedLibatomic@


=====================================
hadrian/cfg/system.config.target.in
=====================================
@@ -0,0 +1,83 @@
+# This file is processed by the configure script.
+# See hadrian/src/UserSettings.hs for user-defined settings.
+#===========================================================
+
+# Paths to builders:
+#===================
+
+# Information about builders:
+#============================
+
+cc-llvm-backend           = @CcLlvmBackend@
+
+
+# Information about build, host and target systems:
+#==================================================
+
+# Q: Is the *-platform information available in the target?
+# A: Yes, it is. We pass @BuildPlatform@ and @HostPlatform@ and @TargetPlatform@ to ghc-toolchain using --target=that
+#     And we can reconstruct the platform info using targetPlatformTriple
+# Q: What is TargetPlatformFull?
+target-platform-full  = @TargetPlatformFull@
+
+dynamic-extension     = @soext_target@
+
+bootstrap-threaded-rts = @GhcThreadedRts@
+
+# Settings:
+#==========
+
+# We are in the process of moving the settings file from being entirely
+# generated by configure, to generated being by the build system. Many of these
+# might become redundant.
+# See Note [tooldir: How GHC finds mingw on Windows]
+
+settings-otool-command = @SettingsOtoolCommand@
+settings-install_name_tool-command = @SettingsInstallNameToolCommand@
+settings-llc-command = @SettingsLlcCommand@
+settings-opt-command = @SettingsOptCommand@
+settings-llvm-as-command = @SettingsLlvmAsCommand@
+settings-use-distro-mingw = @SettingsUseDistroMINGW@
+
+target-has-libm = @TargetHasLibm@
+
+# Include and library directories:
+#=================================
+
+curses-lib-dir     = @CURSES_LIB_DIRS@
+curses-include-dir = @CURSES_INCLUDE_DIRS@
+
+iconv-include-dir = @ICONV_INCLUDE_DIRS@
+iconv-lib-dir     = @ICONV_LIB_DIRS@
+
+intree-gmp              = @GMP_FORCE_INTREE@
+gmp-framework-preferred = @GMP_PREFER_FRAMEWORK@
+gmp-include-dir         = @GMP_INCLUDE_DIRS@
+gmp-lib-dir             = @GMP_LIB_DIRS@
+
+use-system-ffi    = @UseSystemLibFFI@
+ffi-include-dir   = @FFIIncludeDir@
+ffi-lib-dir       = @FFILibDir@
+
+libdw-include-dir   = @LibdwIncludeDir@
+libdw-lib-dir       = @LibdwLibDir@
+
+libnuma-include-dir   = @LibNumaIncludeDir@
+libnuma-lib-dir       = @LibNumaLibDir@
+
+libzstd-include-dir   = @LibZstdIncludeDir@
+libzstd-lib-dir       = @LibZstdLibDir@
+
+# Optional Dependencies:
+#=======================
+
+use-lib-dw        = @UseLibdw@
+use-lib-zstd      = @UseLibZstd@
+static-lib-zstd   = @UseStaticLibZstd@
+use-lib-numa      = @UseLibNuma@
+use-lib-m         = @UseLibm@
+use-lib-rt        = @UseLibrt@
+use-lib-dl        = @UseLibdl@
+use-lib-bfd       = @UseLibbfd@
+use-lib-pthread   = @UseLibpthread@
+need-libatomic    = @NeedLibatomic@


=====================================
hadrian/src/Base.hs
=====================================
@@ -29,7 +29,8 @@ module Base (
     module Way,
 
     -- * Paths
-    hadrianPath, configPath, configFile, sourcePath, shakeFilesDir,
+    hadrianPath, configPath, configFile, buildConfigFileHost, buildConfigFileTarget,
+    sourcePath, shakeFilesDir,
     stageBinPath, stageLibPath, templateHscPath,
     buildTargetFile, hostTargetFile, targetTargetFile,
     ghcLibDeps, haddockDeps,
@@ -80,6 +81,13 @@ configPath = hadrianPath -/- "cfg"
 configFile :: FilePath
 configFile = configPath -/- "system.config"
 
+buildConfigFileHost :: FilePath
+buildConfigFileHost = configPath -/- "system.config.host"
+
+buildConfigFileTarget :: FilePath
+buildConfigFileTarget = configPath -/- "system.config.target"
+
+
 -- | The target configuration file generated by ghc-toolchain for the
 -- compilation build platform
 buildTargetFile :: FilePath


=====================================
hadrian/src/Builder.hs
=====================================
@@ -28,14 +28,13 @@ import Hadrian.Builder.Tar
 import Hadrian.Oracles.Path
 import Hadrian.Oracles.TextFile
 import Hadrian.Utilities
-import Oracles.Setting (bashPath, targetStage)
 import System.Exit
 import System.IO (stderr)
 
 import Base
 import Context
 import Oracles.Flag
-import Oracles.Setting (setting, Setting(..))
+import Oracles.Setting
 import Packages
 
 import GHC.IO.Encoding (getFileSystemEncoding)


=====================================
hadrian/src/Expression.hs
=====================================
@@ -146,7 +146,7 @@ buildingCompilerStage' f = f . succStage <$> getStage
 --   compiler's RTS ways. See Note [Linking ghc-bin against threaded stage0 RTS]
 --   in Settings.Packages for details.
 threadedBootstrapper :: Predicate
-threadedBootstrapper = expr (flag BootstrapThreadedRts)
+threadedBootstrapper = staged (buildFlag BootstrapThreadedRts)
 
 -- | Is a certain package /not/ built right now?
 notPackage :: Package -> Predicate


=====================================
hadrian/src/Hadrian/Oracles/TextFile.hs
=====================================
@@ -13,7 +13,7 @@
 -- to read configuration or package metadata files and cache the parsing.
 -----------------------------------------------------------------------------
 module Hadrian.Oracles.TextFile (
-    lookupValue, lookupValueOrEmpty, lookupValueOrError, lookupSystemConfig, lookupValues,
+    lookupValue, lookupValueOrEmpty, lookupValueOrError, lookupSystemConfig, lookupHostBuildConfig, lookupTargetBuildConfig, lookupValues,
     lookupValuesOrEmpty, lookupValuesOrError, lookupDependencies, textFileOracle,
     getBuildTarget, getHostTarget, getTargetTarget,
     queryBuildTarget, queryHostTarget
@@ -52,6 +52,23 @@ lookupSystemConfig = lookupValueOrError (Just configError) configFile
   where
     configError = "Perhaps you need to rerun ./configure"
 
+lookupHostBuildConfig :: String -> Action String
+lookupHostBuildConfig key = do
+  cross <- (== "YES") <$> lookupSystemConfig "cross-compiling"
+  -- If we are not cross compiling, the build the host compiler like the target.
+  let cfgFile = if cross then buildConfigFileHost else buildConfigFileTarget
+  lookupValueOrError (Just configError) cfgFile key
+  where
+    configError = "Perhaps you need to rerun ./configure"
+
+lookupTargetBuildConfig :: String -> Action String
+lookupTargetBuildConfig key =
+  lookupValueOrError (Just configError) buildConfigFileTarget key
+  where
+    configError = "Perhaps you need to rerun ./configure"
+
+
+
 -- | Lookup a list of values in a text file, tracking the result. Each line of
 -- the file is expected to have @key value1 value2 ...@ format.
 lookupValues :: FilePath -> String -> Action (Maybe [String])
@@ -104,6 +121,7 @@ getHostTarget = do
   -- MP: If we are not cross compiling then we should use the target file in order to
   -- build things for the host, in particular we want to use the configured values for the
   -- target for building the RTS (ie are we using Libffi for adjustors, and the wordsize)
+  -- TODO: Use "flag CrossCompiling"
   ht <- getTargetConfig hostTargetFile
   tt <- getTargetConfig targetTargetFile
   if (Toolchain.targetPlatformTriple ht) == (Toolchain.targetPlatformTriple tt)


=====================================
hadrian/src/Oracles/Flag.hs
=====================================
@@ -2,6 +2,7 @@
 
 module Oracles.Flag (
     Flag (..), flag, getFlag,
+    BuildFlag(..), buildFlag,
     targetSupportsSharedLibs,
     targetSupportsGhciObjects,
     targetSupportsThreadedRts,
@@ -22,7 +23,8 @@ import qualified GHC.Toolchain as Toolchain
 import GHC.Platform.ArchOS
 
 data Flag = CrossCompiling
-          | CcLlvmBackend
+          | UseGhcToolchain
+data BuildFlag = CcLlvmBackend
           | GmpInTree
           | GmpFrameworkPref
           | UseSystemFfi
@@ -38,7 +40,15 @@ data Flag = CrossCompiling
           | UseLibbfd
           | UseLibpthread
           | NeedLibatomic
-          | UseGhcToolchain
+          | TargetHasLibm
+
+parseFlagResult :: String -> String -> Bool
+parseFlagResult key value =
+  if (value `notElem` ["YES", "NO", ""])
+    then error $ "Configuration flag "
+               ++ quote (key ++ " = " ++ value) ++ " cannot be parsed."
+    else value == "YES"
+
 
 -- Note, if a flag is set to empty string we treat it as set to NO. This seems
 -- fragile, but some flags do behave like this.
@@ -46,6 +56,12 @@ flag :: Flag -> Action Bool
 flag f = do
     let key = case f of
             CrossCompiling       -> "cross-compiling"
+            UseGhcToolchain      -> "use-ghc-toolchain"
+    parseFlagResult key <$> lookupSystemConfig key
+
+buildFlag :: BuildFlag -> Stage -> Action Bool
+buildFlag f st =
+    let key = case f of
             CcLlvmBackend        -> "cc-llvm-backend"
             GmpInTree            -> "intree-gmp"
             GmpFrameworkPref     -> "gmp-framework-preferred"
@@ -62,11 +78,13 @@ flag f = do
             UseLibbfd            -> "use-lib-bfd"
             UseLibpthread        -> "use-lib-pthread"
             NeedLibatomic        -> "need-libatomic"
-            UseGhcToolchain      -> "use-ghc-toolchain"
-    value <- lookupSystemConfig key
-    when (value `notElem` ["YES", "NO", ""]) . error $ "Configuration flag "
-        ++ quote (key ++ " = " ++ value) ++ " cannot be parsed."
-    return $ value == "YES"
+            TargetHasLibm        -> "target-has-libm"
+    in parseFlagResult key <$> (tgtConfig st key)
+  where
+    tgtConfig Stage0 {} = lookupHostBuildConfig
+    tgtConfig Stage1 = lookupHostBuildConfig
+    tgtConfig Stage2 = lookupTargetBuildConfig
+    tgtConfig Stage3 = lookupTargetBuildConfig
 
 -- | Get a configuration setting.
 getFlag :: Flag -> Expr c b Bool


=====================================
hadrian/src/Oracles/Setting.hs
=====================================
@@ -1,7 +1,8 @@
 module Oracles.Setting (
     configFile,
     -- * Settings
-    Setting (..), setting, getSetting,
+    ProjectSetting (..), setting, getSetting,
+    BuildSetting(..), buildSetting,
     ToolchainSetting (..), settingsFileSetting,
 
     -- * Helpers
@@ -39,28 +40,14 @@ import GHC.Platform.ArchOS
 -- tracking the result in the Shake database.
 --
 -- * ROMES:TODO: How to handle target-platform-full?
-data Setting = CursesIncludeDir
-             | CursesLibDir
-             | DynamicExtension
-             | FfiIncludeDir
-             | FfiLibDir
-             | GhcMajorVersion
+data ProjectSetting =
+               GhcMajorVersion
              | GhcMinorVersion
              | GhcPatchLevel
              | GhcVersion
              | GhcSourcePath
              | LlvmMinVersion
              | LlvmMaxVersion
-             | GmpIncludeDir
-             | GmpLibDir
-             | IconvIncludeDir
-             | IconvLibDir
-             | LibdwIncludeDir
-             | LibdwLibDir
-             | LibnumaIncludeDir
-             | LibnumaLibDir
-             | LibZstdIncludeDir
-             | LibZstdLibDir
              | ProjectGitCommitId
              | ProjectName
              | ProjectVersion
@@ -73,6 +60,25 @@ data Setting = CursesIncludeDir
              | TargetPlatformFull
              | BourneShell
 
+
+-- Things which configure how a specific stage is built
+data BuildSetting =
+               CursesIncludeDir
+             | CursesLibDir
+             | DynamicExtension
+             | FfiIncludeDir
+             | FfiLibDir
+             | GmpIncludeDir
+             | GmpLibDir
+             | IconvIncludeDir
+             | IconvLibDir
+             | LibdwIncludeDir
+             | LibdwLibDir
+             | LibnumaIncludeDir
+             | LibnumaLibDir
+             | LibZstdIncludeDir
+             | LibZstdLibDir
+
 -- TODO compute solely in Hadrian, removing these variables' definitions
 -- from aclocal.m4 whenever they can be calculated from other variables
 -- already fed into Hadrian.
@@ -93,13 +99,8 @@ data ToolchainSetting
 
 -- | Look up the value of a 'Setting' in @cfg/system.config@, tracking the
 -- result.
-setting :: Setting -> Action String
+setting :: ProjectSetting -> Action String
 setting key = lookupSystemConfig $ case key of
-    CursesIncludeDir   -> "curses-include-dir"
-    CursesLibDir       -> "curses-lib-dir"
-    DynamicExtension   -> "dynamic-extension"
-    FfiIncludeDir      -> "ffi-include-dir"
-    FfiLibDir          -> "ffi-lib-dir"
     GhcMajorVersion    -> "ghc-major-version"
     GhcMinorVersion    -> "ghc-minor-version"
     GhcPatchLevel      -> "ghc-patch-level"
@@ -107,16 +108,6 @@ setting key = lookupSystemConfig $ case key of
     GhcSourcePath      -> "ghc-source-path"
     LlvmMinVersion     -> "llvm-min-version"
     LlvmMaxVersion     -> "llvm-max-version"
-    GmpIncludeDir      -> "gmp-include-dir"
-    GmpLibDir          -> "gmp-lib-dir"
-    IconvIncludeDir    -> "iconv-include-dir"
-    IconvLibDir        -> "iconv-lib-dir"
-    LibdwIncludeDir    -> "libdw-include-dir"
-    LibdwLibDir        -> "libdw-lib-dir"
-    LibnumaIncludeDir  -> "libnuma-include-dir"
-    LibnumaLibDir      -> "libnuma-lib-dir"
-    LibZstdIncludeDir  -> "libzstd-include-dir"
-    LibZstdLibDir      -> "libzstd-lib-dir"
     ProjectGitCommitId -> "project-git-commit-id"
     ProjectName        -> "project-name"
     ProjectVersion     -> "project-version"
@@ -129,22 +120,51 @@ setting key = lookupSystemConfig $ case key of
     TargetPlatformFull -> "target-platform-full"
     BourneShell        -> "bourne-shell"
 
+buildSetting :: BuildSetting -> Stage -> Action String
+buildSetting key stage = tgtConfig stage $ case key of
+    CursesIncludeDir   -> "curses-include-dir"
+    CursesLibDir       -> "curses-lib-dir"
+    DynamicExtension   -> "dynamic-extension"
+    FfiIncludeDir      -> "ffi-include-dir"
+    FfiLibDir          -> "ffi-lib-dir"
+    GmpIncludeDir      -> "gmp-include-dir"
+    GmpLibDir          -> "gmp-lib-dir"
+    IconvIncludeDir    -> "iconv-include-dir"
+    IconvLibDir        -> "iconv-lib-dir"
+    LibdwIncludeDir    -> "libdw-include-dir"
+    LibdwLibDir        -> "libdw-lib-dir"
+    LibnumaIncludeDir  -> "libnuma-include-dir"
+    LibnumaLibDir      -> "libnuma-lib-dir"
+    LibZstdIncludeDir  -> "libzstd-include-dir"
+    LibZstdLibDir      -> "libzstd-lib-dir"
+  where
+    tgtConfig Stage0 {} = lookupHostBuildConfig
+    tgtConfig Stage1 = lookupHostBuildConfig
+    tgtConfig Stage2 = lookupTargetBuildConfig
+    tgtConfig Stage3 = lookupTargetBuildConfig
+
+
 -- | Look up the value of a 'SettingList' in @cfg/system.config@, tracking the
 -- result.
 -- See Note [tooldir: How GHC finds mingw on Windows]
 -- ROMES:TODO: This should be queryTargetTargetConfig
-settingsFileSetting :: ToolchainSetting -> Action String
-settingsFileSetting key = lookupSystemConfig $ case key of
+settingsFileSetting :: ToolchainSetting -> Stage -> Action String
+settingsFileSetting key stage = tgtConfig stage $ case key of
     ToolchainSetting_OtoolCommand           -> "settings-otool-command"
     ToolchainSetting_InstallNameToolCommand -> "settings-install_name_tool-command"
     ToolchainSetting_LlcCommand             -> "settings-llc-command"
     ToolchainSetting_OptCommand             -> "settings-opt-command"
     ToolchainSetting_LlvmAsCommand          -> "settings-llvm-as-command"
     ToolchainSetting_DistroMinGW            -> "settings-use-distro-mingw" -- ROMES:TODO: This option doesn't seem to be in ghc-toolchain yet. It corresponds to EnableDistroToolchain
+  where
+    tgtConfig Stage0 {} = lookupHostBuildConfig
+    tgtConfig Stage1 = lookupHostBuildConfig
+    tgtConfig Stage2 = lookupTargetBuildConfig
+    tgtConfig Stage3 = lookupTargetBuildConfig
 
 -- | An expression that looks up the value of a 'Setting' in @cfg/system.config@,
 -- tracking the result.
-getSetting :: Setting -> Expr c b String
+getSetting :: ProjectSetting -> Expr c b String
 getSetting = expr . setting
 
 -- | The path to a Bourne shell interpreter.
@@ -247,7 +267,7 @@ libsuf :: Stage -> Way -> Action String
 libsuf st way
     | not (wayUnit Dynamic way) = return (waySuffix way ++ ".a") -- e.g., _p.a
     | otherwise = do
-        extension <- setting DynamicExtension -- e.g., .dll or .so
+        extension <- buildSetting DynamicExtension st-- e.g., .dll or .so
         version   <- ghcVersionStage st -- e.g. 8.4.4 or 8.9.xxxx
         let suffix = waySuffix (removeWayUnit Dynamic way)
         return (suffix ++ "-ghc" ++ version ++ extension)


=====================================
hadrian/src/Oracles/TestSettings.hs
=====================================
@@ -10,7 +10,7 @@ module Oracles.TestSettings
 
 import Base
 import Hadrian.Oracles.TextFile
-import Oracles.Setting (topDirectory, setting, Setting(..), crossStage)
+import Oracles.Setting (topDirectory, setting, ProjectSetting(..), crossStage)
 import Packages
 import Settings.Program (programContext)
 import Hadrian.Oracles.Path


=====================================
hadrian/src/Rules/Generate.hs
=====================================
@@ -10,7 +10,6 @@ import qualified Data.Set as Set
 import Base
 import qualified Context
 import Expression
-import Hadrian.Oracles.TextFile (lookupSystemConfig)
 import Oracles.Flag hiding (arSupportsAtFile, arSupportsDashL)
 import Oracles.ModuleFiles
 import Oracles.Setting
@@ -49,10 +48,9 @@ ghcPrimDependencies = do
 
 rtsDependencies :: Expr [FilePath]
 rtsDependencies = do
-    stage   <- getStage
-    rtsPath <- expr (rtsBuildPath stage)
-    jsTarget <- expr (isJsTarget stage)
-    useSystemFfi <- expr (flag UseSystemFfi)
+    rtsPath <- staged rtsBuildPath
+    jsTarget <- staged isJsTarget
+    useSystemFfi <- staged (buildFlag UseSystemFfi)
 
     let -- headers common to native and JS RTS
         common_headers =
@@ -276,7 +274,7 @@ runInterpolations (Interpolations mk_substs) input = do
     return (subst input)
 
 -- | Interpolate the given variable with the value of the given 'Setting'.
-interpolateSetting :: String -> Setting -> Interpolations
+interpolateSetting :: String -> ProjectSetting -> Interpolations
 interpolateSetting name settng = interpolateVar name $ setting settng
 
 -- | Interpolate the @ProjectVersion@ and @ProjectVersionMunged@ variables.
@@ -401,8 +399,8 @@ generateSettings settingsFile = do
         , ("ar supports at file", queryTarget stage arSupportsAtFile')
         , ("ar supports -L",      queryTarget stage arSupportsDashL')
         , ("ranlib command", queryTarget stage ranlibPath)
-        , ("otool command", expr $ settingsFileSetting ToolchainSetting_OtoolCommand)
-        , ("install_name_tool command", expr $ settingsFileSetting ToolchainSetting_InstallNameToolCommand)
+        , ("otool command", staged $ settingsFileSetting ToolchainSetting_OtoolCommand)
+        , ("install_name_tool command", staged $ settingsFileSetting ToolchainSetting_InstallNameToolCommand)
         , ("windres command", queryTarget stage (maybe "/bin/false" prgPath . tgtWindres)) -- TODO: /bin/false is not available on many distributions by default, but we keep it as it were before the ghc-toolchain patch. Fix-me.
         , ("unlit command", ("$topdir/../bin/" <>) <$> expr (programName (ctx { Context.package = unlit, Context.stage = predStage stage })))
         , ("cross compiling", expr $ yesNo <$> crossStage (predStage stage))
@@ -414,13 +412,13 @@ generateSettings settingsFile = do
         , ("target has GNU nonexec stack", queryTarget stage (yesNo . Toolchain.tgtSupportsGnuNonexecStack))
         , ("target has .ident directive",  queryTarget stage (yesNo . Toolchain.tgtSupportsIdentDirective))
         , ("target has subsections via symbols", queryTarget stage (yesNo . Toolchain.tgtSupportsSubsectionsViaSymbols))
-        , ("target has libm", expr $  lookupSystemConfig "target-has-libm")
+        , ("target has libm", yesNo <$> staged (buildFlag TargetHasLibm))
         , ("Unregisterised", queryTarget stage (yesNo . tgtUnregisterised))
         , ("LLVM target", queryTarget stage tgtLlvmTarget)
-        , ("LLVM llc command", expr $ settingsFileSetting ToolchainSetting_LlcCommand)
-        , ("LLVM opt command", expr $ settingsFileSetting ToolchainSetting_OptCommand)
-        , ("LLVM llvm-as command", expr $ settingsFileSetting ToolchainSetting_LlvmAsCommand)
-        , ("Use inplace MinGW toolchain", expr $ settingsFileSetting ToolchainSetting_DistroMinGW)
+        , ("LLVM llc command", staged $ settingsFileSetting ToolchainSetting_LlcCommand)
+        , ("LLVM opt command", staged $ settingsFileSetting ToolchainSetting_OptCommand)
+        , ("LLVM llvm-as command", staged $ settingsFileSetting ToolchainSetting_LlvmAsCommand)
+        , ("Use inplace MinGW toolchain", staged $ settingsFileSetting ToolchainSetting_DistroMinGW)
 
         , ("Use interpreter", expr $ yesNo <$> ghcWithInterpreter stage)
         , ("Support SMP", expr $ yesNo <$> targetSupportsSMP stage)
@@ -428,7 +426,7 @@ generateSettings settingsFile = do
         , ("Tables next to code", queryTarget stage (yesNo . tgtTablesNextToCode))
         , ("Leading underscore",  queryTarget stage (yesNo . tgtSymbolsHaveLeadingUnderscore))
         , ("Use LibFFI", expr $ yesNo <$> targetUseLibffiForAdjustors stage)
-        , ("RTS expects libdw", yesNo <$> getFlag UseLibdw)
+        , ("RTS expects libdw", yesNo <$> staged (buildFlag UseLibdw))
         , ("Relative Global Package DB", pure rel_pkg_db)
         ]
     let showTuple (k, v) = "(" ++ show k ++ ", " ++ show v ++ ")"


=====================================
hadrian/src/Rules/Gmp.hs
=====================================
@@ -17,7 +17,7 @@ import Settings.Builders.Common (cArgs, getStagedCCFlags)
 -- their paths.
 gmpObjects :: Stage -> Action [FilePath]
 gmpObjects s = do
-  isInTree <- flag GmpInTree
+  isInTree <- buildFlag GmpInTree s
   if not isInTree
     then return []
     else do
@@ -65,8 +65,9 @@ gmpRules = do
             packageP   = takeDirectory buildP
             librariesP = takeDirectory packageP
             stageP     = takeDirectory librariesP
+        stage <- parsePath parseStage "<stage>" (takeFileName stageP)
 
-        isInTree <- flag GmpInTree
+        isInTree <- buildFlag GmpInTree stage
 
         if isInTree
         then do


=====================================
hadrian/src/Rules/Libffi.hs
=====================================
@@ -87,7 +87,7 @@ libffiContext stage = do
 -- | The name of the library
 libffiName :: Expr String
 libffiName = do
-    useSystemFfi <- expr (flag UseSystemFfi)
+    useSystemFfi <- staged (buildFlag UseSystemFfi)
     if useSystemFfi
       then pure "ffi"
       else libffiLocalName Nothing
@@ -118,8 +118,8 @@ libffiHeaderDir stage = do
     path <- libffiBuildPath stage
     return $ path -/- "inst/include"
 
-libffiSystemHeaderDir :: Action FilePath
-libffiSystemHeaderDir = setting FfiIncludeDir
+libffiSystemHeaderDir :: Stage -> Action FilePath
+libffiSystemHeaderDir = buildSetting FfiIncludeDir
 
 fixLibffiMakefile :: FilePath -> String -> String
 fixLibffiMakefile top =


=====================================
hadrian/src/Rules/Rts.hs
=====================================
@@ -53,9 +53,9 @@ withLibffi stage action = needLibffi stage
 -- See Note [Packaging libffi headers] in GHC.Driver.CodeOutput.
 copyLibffiHeader :: Stage -> FilePath -> Action ()
 copyLibffiHeader stage header = do
-    useSystemFfi <- flag UseSystemFfi
+    useSystemFfi <- buildFlag UseSystemFfi stage
     (fromStr, headerDir) <- if useSystemFfi
-        then ("system",) <$> libffiSystemHeaderDir
+        then ("system",) <$> libffiSystemHeaderDir stage
         else needLibffi stage
           >> ("custom",) <$> libffiHeaderDir stage
     copyFile
@@ -122,7 +122,7 @@ rtsLibffiLibrary stage way = do
 needRtsLibffiTargets :: Stage -> Action [FilePath]
 needRtsLibffiTargets stage = do
     rtsPath      <- rtsBuildPath stage
-    useSystemFfi <- flag UseSystemFfi
+    useSystemFfi <- buildFlag UseSystemFfi stage
     jsTarget     <- isJsTarget stage
 
     -- Header files (in the rts build dir).


=====================================
hadrian/src/Settings/Builders/Cabal.hs
=====================================
@@ -199,11 +199,11 @@ configureArgs cFlags' ldFlags' = do
     mconcat
         [ conf "CFLAGS"   cFlags
         , conf "LDFLAGS"  ldFlags
-        , conf "--with-iconv-includes"    $ arg =<< getSetting IconvIncludeDir
-        , conf "--with-iconv-libraries"   $ arg =<< getSetting IconvLibDir
-        , conf "--with-gmp-includes"      $ arg =<< getSetting GmpIncludeDir
-        , conf "--with-gmp-libraries"     $ arg =<< getSetting GmpLibDir
-        , conf "--with-curses-libraries"  $ arg =<< getSetting CursesLibDir
+        , conf "--with-iconv-includes"    $ arg =<< staged (buildSetting IconvIncludeDir)
+        , conf "--with-iconv-libraries"   $ arg =<< staged (buildSetting IconvLibDir)
+        , conf "--with-gmp-includes"      $ arg =<< staged (buildSetting GmpIncludeDir)
+        , conf "--with-gmp-libraries"     $ arg =<< staged (buildSetting GmpLibDir)
+        , conf "--with-curses-libraries"  $ arg =<< staged (buildSetting CursesLibDir)
         , conf "--host"                   $ arg =<< flip queryTarget targetPlatformTriple  . predStage' =<< getStage
         , conf "--with-cc" $ arg =<< getBuilderPath . (Cc CompileC) =<< getStage
         , ghcVersionH


=====================================
hadrian/src/Settings/Builders/Common.hs
=====================================
@@ -51,9 +51,9 @@ cppArgs = mempty
 cWarnings :: Args
 cWarnings = mconcat
     [ arg "-Wall"
-    , flag CcLlvmBackend ? arg "-Wno-unknown-pragmas"
-    , notM (flag CcLlvmBackend) ? not windowsHost ? arg "-Werror=unused-but-set-variable"
-    , notM (flag CcLlvmBackend) ? arg "-Wno-error=inline" ]
+    , staged (buildFlag CcLlvmBackend) ? arg "-Wno-unknown-pragmas"
+    , notM (staged (buildFlag CcLlvmBackend)) ? not windowsHost ? arg "-Werror=unused-but-set-variable"
+    , notM (staged (buildFlag CcLlvmBackend)) ? arg "-Wno-error=inline" ]
 
 packageDatabaseArgs :: Args
 packageDatabaseArgs = do


=====================================
hadrian/src/Settings/Builders/Ghc.hs
=====================================
@@ -103,7 +103,7 @@ ghcLinkArgs = builder (Ghc LinkHs) ? do
     st <- getStage
     distDir <- expr (Context.distDir st)
 
-    useSystemFfi <- expr (flag UseSystemFfi)
+    useSystemFfi <- staged (buildFlag UseSystemFfi)
     buildPath <- getBuildPath
     libffiName' <- libffiName
     debugged <- buildingCompilerStage' . ghcDebugged =<< expr flavour


=====================================
hadrian/src/Settings/Builders/Hsc2Hs.hs
=====================================
@@ -12,7 +12,7 @@ hsc2hsBuilderArgs :: Args
 hsc2hsBuilderArgs = builder Hsc2Hs ? do
     stage   <- getStage
     ccPath  <- getBuilderPath $ Cc CompileC stage
-    gmpDir  <- getSetting GmpIncludeDir
+    gmpDir  <- staged (buildSetting GmpIncludeDir)
     top     <- expr topDirectory
     hArch   <- queryHost queryArch
     hOs     <- queryHost queryOS


=====================================
hadrian/src/Settings/Builders/RunTest.hs
=====================================
@@ -114,7 +114,7 @@ inTreeCompilerArgs stg = do
     platform    <- queryTargetTarget ghcStage targetPlatformTriple
     wordsize    <- show @Int . (*8) <$> queryTargetTarget ghcStage (wordSize2Bytes . tgtWordSize)
 
-    llc_cmd   <- settingsFileSetting ToolchainSetting_LlcCommand
+    llc_cmd   <- settingsFileSetting ToolchainSetting_LlcCommand ghcStage
     have_llvm <- liftIO (isJust <$> findExecutable llc_cmd)
 
     top         <- topDirectory


=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -30,10 +30,10 @@ packageArgs = do
 
         compilerStageOption f = buildingCompilerStage' . f =<< expr flavour
 
-    cursesIncludeDir <- getSetting CursesIncludeDir
-    cursesLibraryDir <- getSetting CursesLibDir
-    ffiIncludeDir  <- getSetting FfiIncludeDir
-    ffiLibraryDir  <- getSetting FfiLibDir
+    cursesIncludeDir <- staged (buildSetting CursesIncludeDir)
+    cursesLibraryDir <- staged (buildSetting CursesLibDir)
+    ffiIncludeDir  <- staged (buildSetting FfiIncludeDir)
+    ffiLibraryDir  <- staged (buildSetting FfiLibDir)
     stageVersion <- readVersion <$> (expr $ ghcVersionStage stage)
 
     mconcat
@@ -80,13 +80,13 @@ packageArgs = do
             [ andM [expr (ghcWithInterpreter stage), notStage0] `cabalFlag` "internal-interpreter"
             , notM cross `cabalFlag` "terminfo"
             , arg "-build-tool-depends"
-            , flag UseLibzstd `cabalFlag` "with-libzstd"
+            , staged (buildFlag UseLibzstd) `cabalFlag` "with-libzstd"
             -- ROMES: While the boot compiler is not updated wrt -this-unit-id
             -- not being fixed to `ghc`, when building stage0, we must set
             -- -this-unit-id to `ghc` because the boot compiler expects that.
             -- We do it through a cabal flag in ghc.cabal
             , stageVersion < makeVersion [9,8,1] ? arg "+hadrian-stage0"
-            , flag StaticLibzstd `cabalFlag` "static-libzstd"
+            , staged (buildFlag StaticLibzstd) `cabalFlag` "static-libzstd"
             ]
 
           , builder (Haddock BuildPackage) ? arg ("--optghc=-I" ++ path) ]
@@ -116,9 +116,9 @@ packageArgs = do
 
         -------------------------------- ghcPrim -------------------------------
         , package ghcPrim ? mconcat
-          [ builder (Cabal Flags) ? flag NeedLibatomic `cabalFlag` "need-atomic"
+          [ builder (Cabal Flags) ? staged (buildFlag NeedLibatomic) `cabalFlag` "need-atomic"
 
-          , builder (Cc CompileC) ? (not <$> flag CcLlvmBackend) ?
+          , builder (Cc CompileC) ? (not <$> staged (buildFlag CcLlvmBackend)) ?
             input "**/cbits/atomic.c"  ? arg "-Wno-sync-nand" ]
 
         --------------------------------- ghci ---------------------------------
@@ -229,8 +229,8 @@ packageArgs = do
 ghcBignumArgs :: Args
 ghcBignumArgs = package ghcBignum ? do
     -- These are only used for non-in-tree builds.
-    librariesGmp <- getSetting GmpLibDir
-    includesGmp <- getSetting GmpIncludeDir
+    librariesGmp <- staged (buildSetting GmpLibDir)
+    includesGmp <- staged (buildSetting GmpIncludeDir)
 
     backend <- getBignumBackend
     check   <- getBignumCheck
@@ -253,15 +253,15 @@ ghcBignumArgs = package ghcBignum ? do
 
                        -- enable in-tree support: don't depend on external "gmp"
                        -- library
-                     , flag GmpInTree ? arg "--configure-option=--with-intree-gmp"
+                     , staged (buildFlag GmpInTree) ? arg "--configure-option=--with-intree-gmp"
 
                        -- prefer framework over library (on Darwin)
-                     , flag GmpFrameworkPref ?
+                     , staged (buildFlag GmpFrameworkPref) ?
                        arg "--configure-option=--with-gmp-framework-preferred"
 
                        -- Ensure that the ghc-bignum package registration includes
                        -- knowledge of the system gmp's library and include directories.
-                     , notM (flag GmpInTree) ? cabalExtraDirs includesGmp librariesGmp
+                     , notM (staged (buildFlag GmpInTree)) ? cabalExtraDirs includesGmp librariesGmp
                      ]
                   ]
                _ -> mempty
@@ -290,15 +290,15 @@ rtsPackageArgs = package rts ? do
     way            <- getWay
     path           <- getBuildPath
     top            <- expr topDirectory
-    useSystemFfi   <- getFlag UseSystemFfi
-    ffiIncludeDir  <- getSetting FfiIncludeDir
-    ffiLibraryDir  <- getSetting FfiLibDir
-    libdwIncludeDir   <- getSetting LibdwIncludeDir
-    libdwLibraryDir   <- getSetting LibdwLibDir
-    libnumaIncludeDir <- getSetting LibnumaIncludeDir
-    libnumaLibraryDir <- getSetting LibnumaLibDir
-    libzstdIncludeDir <- getSetting LibZstdIncludeDir
-    libzstdLibraryDir <- getSetting LibZstdLibDir
+    useSystemFfi   <- staged (buildFlag UseSystemFfi)
+    ffiIncludeDir  <- staged (buildSetting FfiIncludeDir)
+    ffiLibraryDir  <- staged (buildSetting FfiLibDir)
+    libdwIncludeDir   <- staged (buildSetting LibdwIncludeDir)
+    libdwLibraryDir   <- staged (buildSetting LibdwLibDir)
+    libnumaIncludeDir <- staged (buildSetting LibnumaIncludeDir)
+    libnumaLibraryDir <- staged (buildSetting LibnumaLibDir)
+    libzstdIncludeDir <- staged (buildSetting LibZstdIncludeDir)
+    libzstdLibraryDir <- staged (buildSetting LibZstdLibDir)
 
 
     -- Arguments passed to GHC when compiling C and .cmm sources.
@@ -392,10 +392,10 @@ rtsPackageArgs = package rts ? do
           -- any warnings in the module. See:
           -- https://gitlab.haskell.org/ghc/ghc/wikis/working-conventions#Warnings
 
-          , (not <$> flag CcLlvmBackend) ?
+          , (not <$> staged (buildFlag CcLlvmBackend)) ?
             inputs ["**/Compact.c"] ? arg "-finline-limit=2500"
 
-          , input "**/RetainerProfile.c" ? flag CcLlvmBackend ?
+          , input "**/RetainerProfile.c" ? staged (buildFlag CcLlvmBackend) ?
             arg "-Wno-incompatible-pointer-types"
           ]
 
@@ -405,18 +405,18 @@ rtsPackageArgs = package rts ? do
           , any (wayUnit Debug) rtsWays     `cabalFlag` "debug"
           , any (wayUnit Dynamic) rtsWays   `cabalFlag` "dynamic"
           , any (wayUnit Threaded) rtsWays  `cabalFlag` "threaded"
-          , flag UseLibm                    `cabalFlag` "libm"
-          , flag UseLibrt                   `cabalFlag` "librt"
-          , flag UseLibdl                   `cabalFlag` "libdl"
+          , staged (buildFlag UseLibm)                    `cabalFlag` "libm"
+          , staged (buildFlag UseLibrt)                   `cabalFlag` "librt"
+          , staged (buildFlag UseLibdl)                   `cabalFlag` "libdl"
           , useSystemFfi                    `cabalFlag` "use-system-libffi"
           , targetUseLibffiForAdjustors stage     `cabalFlag` "libffi-adjustors"
-          , flag UseLibpthread              `cabalFlag` "need-pthread"
-          , flag UseLibbfd                  `cabalFlag` "libbfd"
-          , flag NeedLibatomic              `cabalFlag` "need-atomic"
-          , flag UseLibdw                   `cabalFlag` "libdw"
-          , flag UseLibnuma                 `cabalFlag` "libnuma"
-          , flag UseLibzstd                 `cabalFlag` "libzstd"
-          , flag StaticLibzstd              `cabalFlag` "static-libzstd"
+          , staged (buildFlag UseLibpthread)             `cabalFlag` "need-pthread"
+          , staged (buildFlag UseLibbfd    )              `cabalFlag` "libbfd"
+          , staged (buildFlag NeedLibatomic)              `cabalFlag` "need-atomic"
+          , staged (buildFlag UseLibdw     )              `cabalFlag` "libdw"
+          , staged (buildFlag UseLibnuma   )              `cabalFlag` "libnuma"
+          , staged (buildFlag UseLibzstd   )              `cabalFlag` "libzstd"
+          , staged (buildFlag StaticLibzstd)              `cabalFlag` "static-libzstd"
           , queryTargetTarget stage tgtSymbolsHaveLeadingUnderscore `cabalFlag` "leading-underscore"
           , ghcUnreg                        `cabalFlag` "unregisterised"
           , ghcEnableTNC                    `cabalFlag` "tables-next-to-code"
@@ -437,7 +437,7 @@ rtsPackageArgs = package rts ? do
         , builder HsCpp ? pure
           [ "-DTOP="             ++ show top ]
 
-        , builder HsCpp ? flag UseLibdw ? arg "-DUSE_LIBDW" ]
+        , builder HsCpp ? staged (buildFlag UseLibdw) ? arg "-DUSE_LIBDW" ]
 
 -- Compile various performance-critical pieces *without* -fPIC -dynamic
 -- even when building a shared library.  If we don't do this, then the


=====================================
hadrian/src/Settings/Warnings.hs
=====================================
@@ -10,16 +10,15 @@ import Packages
 -- | Default Haskell warning-related arguments.
 defaultGhcWarningsArgs :: Args
 defaultGhcWarningsArgs = do
-   stage <- getStage
    mconcat
     [ notStage0 ? arg "-Wnoncanonical-monad-instances"
-    , notM (flag CcLlvmBackend) ? arg "-optc-Wno-error=inline"
-    , flag CcLlvmBackend ? arg "-optc-Wno-unknown-pragmas"
+    , notM (staged (buildFlag CcLlvmBackend)) ? arg "-optc-Wno-error=inline"
+    , staged (buildFlag CcLlvmBackend) ? arg "-optc-Wno-unknown-pragmas"
       -- Cabal can seemingly produce filepaths with incorrect case on filesystems
       -- with case-insensitive names. Ignore such issues for now as they seem benign.
       -- See #17798.
-    , isOsxTarget stage ? arg "-optP-Wno-nonportable-include-path"
-    , isWinTarget stage ? arg "-optP-Wno-nonportable-include-path"
+    , staged isOsxTarget ? arg "-optP-Wno-nonportable-include-path"
+    , staged isWinTarget ? arg "-optP-Wno-nonportable-include-path"
     ]
 
 -- | Package-specific warnings-related arguments, mostly suppressing various warnings.



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04bc9786e169cb88ca4a15a9d28e1819b58ee7a8

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/04bc9786e169cb88ca4a15a9d28e1819b58ee7a8
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20240308/0838a3da/attachment-0001.html>


More information about the ghc-commits mailing list