[Git][ghc/ghc][wip/torsten.schmits/mercury-fixed] release
by Torsten Schmits (@torsten.schmits) 22 Oct '25
by Torsten Schmits (@torsten.schmits) 22 Oct '25
22 Oct '25
Torsten Schmits pushed to branch wip/torsten.schmits/mercury-fixed at Glasgow Haskell Compiler / GHC
Commits:
7485f4b7 by Torsten Schmits at 2025-10-22T16:45:15+02:00
release
- - - - -
2 changed files:
- configure.ac
- utils/haddock/haddock-api/haddock-api.cabal
Changes:
=====================================
configure.ac
=====================================
@@ -13,7 +13,7 @@ dnl
# see what flags are available. (Better yet, read the documentation!)
#
-AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.13], [glasgow-haskell-bugs(a)haskell.org] [ghc-AC_PACKAGE_VERSION])
+AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.12.1], [glasgow-haskell-bugs(a)haskell.org] [ghc-AC_PACKAGE_VERSION])
# Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable
# to be useful (cf #19058). However, the version must have three components
# (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are
@@ -22,7 +22,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.13], [glasgow-hask
AC_CONFIG_MACRO_DIRS([m4])
# Set this to YES for a released version, otherwise NO
-: ${RELEASE=NO}
+: ${RELEASE=YES}
# The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line
# above. If this is not a released version, then we will append the
=====================================
utils/haddock/haddock-api/haddock-api.cabal
=====================================
@@ -79,7 +79,7 @@ library
-- this package typically supports only single major versions
build-depends: base >= 4.16 && < 4.22
- , ghc ^>= 9.13
+ , ghc ^>= 9.12
, haddock-library ^>= 1.11
, xhtml ^>= 3000.2.2
, parsec ^>= 3.1.13.0
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7485f4b75189fc8d00104318a96a4c6…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/7485f4b75189fc8d00104318a96a4c6…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/torsten.schmits/mercury-fixed] 2 commits: driver: add -dep-json -opt-json flags to ghc -M
by Torsten Schmits (@torsten.schmits) 22 Oct '25
by Torsten Schmits (@torsten.schmits) 22 Oct '25
22 Oct '25
Torsten Schmits pushed to branch wip/torsten.schmits/mercury-fixed at Glasgow Haskell Compiler / GHC
Commits:
b7ef1743 by Cheng Shao at 2025-10-22T15:39:51+02:00
driver: add -dep-json -opt-json flags to ghc -M
docs: document -dep-json -opt-json flags
Rework protocol
merge opt-json into dep-json
normalize source filenames
include more canonical variant of the package id
choose the main library when -package matches multiple units with the same version
allow specifying library deps with -package pkg:lib
Backported to GHC 9.10
- - - - -
dbb1df4d by Torsten Schmits at 2025-10-22T15:39:51+02:00
release
- - - - -
25 changed files:
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/MakeFile.hs
- + compiler/GHC/Driver/MakeFile/JSON.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/State.hs
- compiler/ghc.cabal.in
- configure.ac
- docs/users_guide/separate_compilation.rst
- docs/users_guide/using.rst
- + testsuite/tests/driver/T24384/A.hs
- + testsuite/tests/driver/T24384/B.hs
- + testsuite/tests/driver/T24384/C.hs
- + testsuite/tests/driver/T24384/C.hs-boot
- + testsuite/tests/driver/T24384/D.hs
- + testsuite/tests/driver/T24384/E.hs
- + testsuite/tests/driver/T24384/Makefile
- + testsuite/tests/driver/T24384/T24384.stdout
- + testsuite/tests/driver/T24384/all.T
- + testsuite/tests/driver/T24384/preproc.sh
- + testsuite/tests/driver/T24384/setup-dep.sh
Changes:
=====================================
compiler/GHC/Driver/Backpack.hs
=====================================
@@ -804,6 +804,7 @@ summariseRequirement pn mod_name = do
ms_hie_date = hie_timestamp,
ms_srcimps = [],
ms_textual_imps = ((,) NoPkgQual . noLoc) <$> extra_sig_imports,
+ ms_opts = [],
ms_parsed_mod = Just (HsParsedModule {
hpm_module = L loc (HsModule {
hsmodExt = XModulePs {
@@ -909,6 +910,7 @@ hsModuleToModSummary home_keys pn hsc_src modname
-- extra imports
++ ((,) NoPkgQual . noLoc <$> extra_sig_imports)
++ ((,) NoPkgQual . noLoc <$> implicit_sigs),
+ ms_opts = [],
-- This is our hack to get the parse tree to the right spot
ms_parsed_mod = Just (HsParsedModule {
hpm_module = hsmod,
=====================================
compiler/GHC/Driver/Downsweep.hs
=====================================
@@ -27,7 +27,7 @@ import GHC.Tc.Utils.Backpack
import GHC.Platform.Ways
import GHC.Driver.Config.Finder (initFinderOpts)
-import GHC.Driver.Config.Parser (initParserOpts)
+import GHC.Driver.Config.Parser (initParserOpts, supportedLanguagePragmas)
import GHC.Driver.Phases
import GHC.Driver.Pipeline
import GHC.Driver.Session
@@ -819,6 +819,7 @@ summariseFile hsc_env' home_unit old_summaries src_fn mb_phase maybe_buf
, nms_location = location
, nms_mod = mod
, nms_preimps = preimps
+ , nms_opts = pi_mod_opts
}
checkSummaryHash
@@ -981,6 +982,7 @@ summariseModule hsc_env' home_unit old_summary_map is_boot (L _ wanted_mod) mb_p
, nms_location = location
, nms_mod = mod
, nms_preimps = preimps
+ , nms_opts = pi_mod_opts
}
-- | Convenience named arguments for 'makeNewModSummary' only used to make
@@ -993,6 +995,7 @@ data MakeNewModSummary
, nms_location :: ModLocation
, nms_mod :: Module
, nms_preimps :: PreprocessedImports
+ , nms_opts :: ![String]
}
makeNewModSummary :: HscEnv -> MakeNewModSummary -> IO ModSummary
@@ -1020,6 +1023,7 @@ makeNewModSummary hsc_env MakeNewModSummary{..} = do
((,) NoPkgQual . noLoc <$> extra_sig_imports) ++
((,) NoPkgQual . noLoc <$> implicit_sigs) ++
pi_theimps
+ , ms_opts = nms_opts
, ms_hs_hash = nms_src_hash
, ms_iface_date = hi_timestamp
, ms_hie_date = hie_timestamp
@@ -1036,6 +1040,7 @@ data PreprocessedImports
, pi_hspp_buf :: StringBuffer
, pi_mod_name_loc :: SrcSpan
, pi_mod_name :: ModuleName
+ , pi_mod_opts :: ![String]
}
-- Preprocess the source file and get its imports
@@ -1051,14 +1056,15 @@ getPreprocessedImports hsc_env src_fn mb_phase maybe_buf = do
(pi_local_dflags, pi_hspp_fn)
<- ExceptT $ preprocess hsc_env src_fn (fst <$> maybe_buf) mb_phase
pi_hspp_buf <- liftIO $ hGetStringBuffer pi_hspp_fn
- (pi_srcimps', pi_theimps', L pi_mod_name_loc pi_mod_name)
+ ((pi_srcimps', pi_theimps', L pi_mod_name_loc pi_mod_name), pi_mod_opts)
<- ExceptT $ do
let imp_prelude = xopt LangExt.ImplicitPrelude pi_local_dflags
popts = initParserOpts pi_local_dflags
mimps <- getImports popts imp_prelude pi_hspp_buf pi_hspp_fn src_fn
- return (first (mkMessages . fmap mkDriverPsHeaderMessage . getMessages) mimps)
+ let mopts = map unLoc $ snd $ getOptions popts (supportedLanguagePragmas pi_local_dflags) pi_hspp_buf src_fn
+ pure $ ((, mopts) <$>) $ first (mkMessages . fmap mkDriverPsHeaderMessage . getMessages) mimps
let rn_pkg_qual = renameRawPkgQual (hsc_unit_env hsc_env)
let rn_imps = fmap (\(pk, lmn@(L _ mn)) -> (rn_pkg_qual mn pk, lmn))
let pi_srcimps = rn_imps pi_srcimps'
let pi_theimps = rn_imps pi_theimps'
- return PreprocessedImports {..}
\ No newline at end of file
+ return PreprocessedImports {..}
=====================================
compiler/GHC/Driver/DynFlags.hs
=====================================
@@ -338,6 +338,7 @@ data DynFlags = DynFlags {
depIncludeCppDeps :: Bool,
depExcludeMods :: [ModuleName],
depSuffixes :: [String],
+ depJSON :: !(Maybe FilePath),
-- Package flags
packageDBFlags :: [PackageDBFlag],
@@ -667,6 +668,7 @@ defaultDynFlags mySettings =
depIncludeCppDeps = False,
depExcludeMods = [],
depSuffixes = [],
+ depJSON = Nothing,
-- end of ghc -M values
ghcVersionFile = Nothing,
haddockOptions = Nothing,
=====================================
compiler/GHC/Driver/MakeFile.hs
=====================================
@@ -1,4 +1,5 @@
-
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE NamedFieldPuns #-}
-----------------------------------------------------------------------------
--
@@ -17,15 +18,21 @@ where
import GHC.Prelude
import qualified GHC
+import GHC.Data.Maybe
import GHC.Driver.Make
import GHC.Driver.Monad
import GHC.Driver.DynFlags
+import GHC.Driver.MakeFile.JSON
import GHC.Utils.Misc
import GHC.Driver.Env
import GHC.Driver.Errors.Types
+import GHC.Driver.Pipeline (runPipeline, TPhase (T_Unlit, T_FileArgs), use, mkPipeEnv)
+import GHC.Driver.Phases (StopPhase (StopPreprocess), startPhase, Phase (Unlit))
+import GHC.Driver.Pipeline.Monad (PipelineOutput (NoOutputFile))
+import GHC.Driver.Session (pgm_F)
import qualified GHC.SysTools as SysTools
import GHC.Data.Graph.Directed ( SCC(..) )
-import GHC.Data.OsPath (unsafeDecodeUtf)
+import GHC.Data.OsPath (unsafeDecodeUtf, unsafeEncodeUtf)
import GHC.Utils.Outputable
import GHC.Utils.Panic
import GHC.Types.SourceError
@@ -35,11 +42,13 @@ import Data.List (partition)
import GHC.Utils.TmpFs
import GHC.Iface.Load (cannotFindModule)
+import GHC.Iface.Errors.Types
import GHC.Unit.Module
import GHC.Unit.Module.ModSummary
import GHC.Unit.Module.Graph
import GHC.Unit.Finder
+import GHC.Unit.State (lookupUnitId)
import GHC.Utils.Exception
import GHC.Utils.Error
@@ -49,11 +58,10 @@ import System.Directory
import System.FilePath
import System.IO
import System.IO.Error ( isEOFError )
-import Control.Monad ( when, forM_ )
-import Data.Maybe ( isJust )
+import Control.Monad ( when )
+import Data.Foldable (traverse_)
import Data.IORef
import qualified Data.Set as Set
-import GHC.Iface.Errors.Types
import Data.Either
-----------------------------------------------------------------
@@ -110,7 +118,7 @@ doMkDependModuleGraph dflags module_graph = do
-- and complaining about cycles
hsc_env <- getSession
root <- liftIO getCurrentDirectory
- mapM_ (liftIO . processDeps dflags hsc_env excl_mods root (mkd_tmp_hdl files)) sorted
+ mapM_ (liftIO . processDeps dflags hsc_env excl_mods root (mkd_tmp_hdl files) (mkd_dep_json files)) sorted
-- If -ddump-mod-cycles, show cycles in the module graph
liftIO $ dumpModCycles logger module_graph
@@ -118,13 +126,6 @@ doMkDependModuleGraph dflags module_graph = do
-- Tidy up
liftIO $ endMkDependHS logger files
- -- Unconditional exiting is a bad idea. If an error occurs we'll get an
- --exception; if that is not caught it's fine, but at least we have a
- --chance to find out exactly what went wrong. Uncomment the following
- --line if you disagree.
-
- --`GHC.ghcCatch` \_ -> io $ exitWith (ExitFailure 1)
-
-----------------------------------------------------------------
--
-- beginMkDependHs
@@ -137,6 +138,8 @@ doMkDependModuleGraph dflags module_graph = do
data MkDepFiles
= MkDep { mkd_make_file :: FilePath, -- Name of the makefile
mkd_make_hdl :: Maybe Handle, -- Handle for the open makefile
+ -- | Output interface for the -dep-json file
+ mkd_dep_json :: !(Maybe (JsonOutput DepJSON)),
mkd_tmp_file :: FilePath, -- Name of the temporary file
mkd_tmp_hdl :: Handle } -- Handle of the open temporary file
@@ -179,14 +182,15 @@ beginMkDependHS logger tmpfs dflags = do
return (Just makefile_hdl)
+ dep_json_ref <- mkJsonOutput initDepJSON (depJSON dflags)
-- write the magic marker into the tmp file
hPutStrLn tmp_hdl depStartMarker
return (MkDep { mkd_make_file = makefile, mkd_make_hdl = mb_make_hdl,
+ mkd_dep_json = dep_json_ref,
mkd_tmp_file = tmp_file, mkd_tmp_hdl = tmp_hdl})
-
-----------------------------------------------------------------
--
-- processDeps
@@ -198,6 +202,7 @@ processDeps :: DynFlags
-> [ModuleName]
-> FilePath
-> Handle -- Write dependencies to here
+ -> Maybe (JsonOutput DepJSON)
-> SCC ModuleGraphNode
-> IO ()
-- Write suitable dependencies to handle
@@ -215,79 +220,83 @@ processDeps :: DynFlags
--
-- For {-# SOURCE #-} imports the "hi" will be "hi-boot".
-processDeps _ _ _ _ _ (CyclicSCC nodes)
+processDeps _ _ _ _ _ _ (CyclicSCC nodes)
= -- There shouldn't be any cycles; report them
throwOneError $ cyclicModuleErr nodes
-processDeps _ _ _ _ _ (AcyclicSCC (InstantiationNode _uid node))
+processDeps _ _ _ _ _ _ (AcyclicSCC (InstantiationNode _uid node))
= -- There shouldn't be any backpack instantiations; report them as well
throwOneError $
mkPlainErrorMsgEnvelope noSrcSpan $
GhcDriverMessage $ DriverInstantiationNodeInDependencyGeneration node
-processDeps _dflags _ _ _ _ (AcyclicSCC (LinkNode {})) = return ()
-processDeps _dflags _ _ _ _ (AcyclicSCC (UnitNode {})) = return ()
-processDeps _ _ _ _ _ (AcyclicSCC (ModuleNode _ (ModuleNodeFixed {})))
+processDeps _dflags _ _ _ _ _ (AcyclicSCC (LinkNode {})) = return ()
+processDeps _dflags _ _ _ _ _ (AcyclicSCC (UnitNode {})) = return ()
+processDeps _ _ _ _ _ _ (AcyclicSCC (ModuleNode _ (ModuleNodeFixed {})))
-- No dependencies needed for fixed modules (already compiled)
= return ()
-processDeps dflags hsc_env excl_mods root hdl (AcyclicSCC (ModuleNode _ (ModuleNodeCompile node)))
- = do { let extra_suffixes = depSuffixes dflags
- include_pkg_deps = depIncludePkgDeps dflags
- src_file = msHsFilePath node
- obj_file = msObjFilePath node
- obj_files = insertSuffixes obj_file extra_suffixes
-
- do_imp loc is_boot pkg_qual imp_mod
- = do { mb_hi <- findDependency hsc_env loc pkg_qual imp_mod
- is_boot include_pkg_deps
- ; case mb_hi of {
- Nothing -> return () ;
- Just hi_file -> do
- { let hi_files = insertSuffixes hi_file extra_suffixes
- write_dep (obj,hi) = writeDependency root hdl [obj] hi
-
- -- Add one dependency for each suffix;
- -- e.g. A.o : B.hi
- -- A.x_o : B.x_hi
- ; mapM_ write_dep (obj_files `zip` hi_files) }}}
-
-
- -- Emit std dependency of the object(s) on the source file
- -- Something like A.o : A.hs
- ; writeDependency root hdl obj_files src_file
-
- -- add dependency between objects and their corresponding .hi-boot
- -- files if the module has a corresponding .hs-boot file (#14482)
- ; when (isBootSummary node == IsBoot) $ do
- let hi_boot = msHiFilePath node
- let obj = unsafeDecodeUtf $ removeBootSuffix (msObjFileOsPath node)
- forM_ extra_suffixes $ \suff -> do
- let way_obj = insertSuffixes obj [suff]
- let way_hi_boot = insertSuffixes hi_boot [suff]
- mapM_ (writeDependency root hdl way_obj) way_hi_boot
-
- -- Emit a dependency for each CPP import
- ; when (depIncludeCppDeps dflags) $ do
- -- CPP deps are discovered in the module parsing phase by parsing
- -- comment lines left by the preprocessor.
- -- Note that GHC.parseModule may throw an exception if the module
- -- fails to parse, which may not be desirable (see #16616).
- { session <- Session <$> newIORef hsc_env
- ; parsedMod <- reflectGhc (GHC.parseModule node) session
- ; mapM_ (writeDependency root hdl obj_files)
- (GHC.pm_extra_src_files parsedMod)
- }
-
- -- Emit a dependency for each import
-
- ; let do_imps is_boot idecls = sequence_
- [ do_imp loc is_boot mb_pkg mod
- | (mb_pkg, L loc mod) <- idecls,
- mod `notElem` excl_mods ]
-
- ; do_imps IsBoot (ms_srcimps node)
- ; do_imps NotBoot (ms_imps node)
- }
+
+processDeps dflags hsc_env excl_mods root hdl m_dep_json (AcyclicSCC (ModuleNode _ (ModuleNodeCompile node))) = do
+ pp <- preprocessor
+ deps <- fmap concat $ sequence $
+ [cpp_deps | depIncludeCppDeps dflags] ++ [
+ import_deps IsBoot (ms_srcimps node),
+ import_deps NotBoot (ms_imps node)
+ ]
+ updateJson m_dep_json (updateDepJSON include_pkg_deps pp dep_node deps)
+ writeDependencies include_pkg_deps root hdl extra_suffixes dep_node deps
+ where
+ extra_suffixes = depSuffixes dflags
+ include_pkg_deps = depIncludePkgDeps dflags
+ src_file = msHsFilePath node
+ dep_node =
+ DepNode {
+ dn_mod = ms_mod node,
+ dn_src = src_file,
+ dn_obj = msObjFilePath node,
+ dn_hi = msHiFilePath node,
+ dn_boot = isBootSummary node,
+ dn_options = Set.fromList (ms_opts node)
+ }
+
+ preprocessor
+ | Just src <- ml_hs_file (ms_location node)
+ = runPipeline (hsc_hooks hsc_env) $ do
+ let (_, suffix) = splitExtension src
+ lit | Unlit _ <- startPhase suffix = True
+ | otherwise = False
+ pipe_env = mkPipeEnv StopPreprocess src Nothing NoOutputFile
+ unlit_fn <- if lit then use (T_Unlit pipe_env hsc_env src) else pure src
+ (dflags1, _, _) <- use (T_FileArgs hsc_env unlit_fn)
+ let pp = pgm_F dflags1
+ pure (if null pp then global_preprocessor else Just pp)
+ | otherwise
+ = pure global_preprocessor
+
+ global_preprocessor
+ | let pp = pgm_F dflags
+ , not (null pp)
+ = Just pp
+ | otherwise
+ = Nothing
+
+ -- Emit a dependency for each CPP import
+ -- CPP deps are discovered in the module parsing phase by parsing
+ -- comment lines left by the preprocessor.
+ -- Note that GHC.parseModule may throw an exception if the module
+ -- fails to parse, which may not be desirable (see #16616).
+ cpp_deps = do
+ session <- Session <$> newIORef hsc_env
+ parsedMod <- reflectGhc (GHC.parseModule node) session
+ pure (DepCpp <$> GHC.pm_extra_src_files parsedMod)
+
+ -- Emit a dependency for each import
+ import_deps is_boot idecls =
+ sequence [
+ findDependency hsc_env loc mb_pkg mod is_boot
+ | (mb_pkg, L loc mod) <- idecls
+ , mod `notElem` excl_mods
+ ]
findDependency :: HscEnv
@@ -295,27 +304,78 @@ findDependency :: HscEnv
-> PkgQual -- package qualifier, if any
-> ModuleName -- Imported module
-> IsBootInterface -- Source import
- -> Bool -- Record dependency on package modules
- -> IO (Maybe FilePath) -- Interface file
-findDependency hsc_env srcloc pkg imp is_boot include_pkg_deps = do
+ -> IO Dep
+findDependency hsc_env srcloc pkg imp dep_boot = do
-- Find the module; this will be fast because
-- we've done it once during downsweep
- r <- findImportedModuleWithIsBoot hsc_env imp is_boot pkg
- case r of
- Found loc _
- -- Home package: just depend on the .hi or hi-boot file
- | isJust (ml_hs_file loc) || include_pkg_deps
- -> return (Just (ml_hi_file loc))
-
- -- Not in this package: we don't need a dependency
- | otherwise
- -> return Nothing
+ findImportedModule hsc_env imp pkg >>= \case
+ Found loc dep_mod ->
+ pure DepHi {
+ dep_mod,
+ dep_path = ml_hi_file loc,
+ dep_unit = lookupUnitId (hsc_units hsc_env) (moduleUnitId dep_mod),
+ dep_local,
+ dep_boot
+ }
+ where
+ dep_local = isJust (ml_hs_file loc)
fail ->
- throwOneError $
- mkPlainErrorMsgEnvelope srcloc $
- GhcDriverMessage $ DriverInterfaceError $
- (Can'tFindInterface (cannotFindModule hsc_env imp fail) (LookingForModule imp is_boot))
+ throwOneError $
+ mkPlainErrorMsgEnvelope srcloc $
+ GhcDriverMessage $
+ DriverInterfaceError $
+ Can'tFindInterface (cannotFindModule hsc_env imp fail) $
+ LookingForModule imp dep_boot
+
+writeDependencies ::
+ Bool ->
+ FilePath ->
+ Handle ->
+ [FilePath] ->
+ DepNode ->
+ [Dep] ->
+ IO ()
+writeDependencies include_pkgs root hdl suffixes node deps =
+ traverse_ write tasks
+ where
+ tasks = source_dep : boot_dep ++ concatMap import_dep deps
+
+ -- Emit std dependency of the object(s) on the source file
+ -- Something like A.o : A.hs
+ source_dep = (obj_files, dn_src)
+
+ -- add dependency between objects and their corresponding .hi-boot
+ -- files if the module has a corresponding .hs-boot file (#14482)
+ boot_dep
+ | IsBoot <- dn_boot
+ = [([obj], hi) | (obj, hi) <- zip (suffixed (viaOsPath removeBootSuffix dn_obj)) (suffixed dn_hi)]
+ | otherwise
+ = []
+
+ -- Add one dependency for each suffix;
+ -- e.g. A.o : B.hi
+ -- A.x_o : B.x_hi
+ import_dep = \case
+ DepHi {dep_path, dep_boot, dep_unit}
+ | isNothing dep_unit || include_pkgs
+ , let path = if dep_boot == IsBoot then viaOsPath addBootSuffix dep_path else dep_path
+ -> [([obj], hi) | (obj, hi) <- zip obj_files (suffixed path)]
+
+ | otherwise
+ -> []
+
+ DepCpp {dep_path} -> [(obj_files, dep_path)]
+
+ write (from, to) = writeDependency root hdl from to
+
+ obj_files = suffixed dn_obj
+
+ suffixed f = insertSuffixes f suffixes
+
+ DepNode {dn_src, dn_obj, dn_hi, dn_boot} = node
+
+ viaOsPath f a = unsafeDecodeUtf (f (unsafeEncodeUtf a))
-----------------------------
writeDependency :: FilePath -> Handle -> [FilePath] -> FilePath -> IO ()
@@ -357,8 +417,9 @@ insertSuffixes file_name extras
endMkDependHS :: Logger -> MkDepFiles -> IO ()
endMkDependHS logger
- (MkDep { mkd_make_file = makefile, mkd_make_hdl = makefile_hdl,
- mkd_tmp_file = tmp_file, mkd_tmp_hdl = tmp_hdl })
+ (MkDep { mkd_make_file = makefile, mkd_make_hdl = makefile_hdl,
+ mkd_dep_json,
+ mkd_tmp_file = tmp_file, mkd_tmp_hdl = tmp_hdl })
= do
-- write the magic marker into the tmp file
hPutStrLn tmp_hdl depEndMarker
@@ -381,6 +442,10 @@ endMkDependHS logger
showPass logger "Installing new makefile"
SysTools.copyFile tmp_file makefile
+ -- Write the dependency and option data to a json file if the corresponding
+ -- flags were specified.
+ writeJsonOutput mkd_dep_json
+
-----------------------------------------------------------------
-- Module cycles
=====================================
compiler/GHC/Driver/MakeFile/JSON.hs
=====================================
@@ -0,0 +1,221 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DerivingVia #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE NoFieldSelectors #-}
+{-# LANGUAGE RecordWildCards #-}
+module GHC.Driver.MakeFile.JSON
+ ( writeJSONFile,
+ JsonOutput (..),
+ mkJsonOutput,
+ updateJson,
+ writeJsonOutput,
+ DepJSON,
+ DepNode (..),
+ Dep (..),
+ initDepJSON,
+ updateDepJSON,
+ )
+where
+
+import Data.Foldable (traverse_)
+import Data.IORef
+import qualified Data.Map.Strict as Map
+import qualified Data.Semigroup as Semigroup
+import qualified Data.Set as Set
+import GHC.Data.FastString (unpackFS)
+import GHC.Generics (Generic, Generically (Generically))
+import GHC.Prelude
+import GHC.Unit
+import GHC.Utils.Json
+import GHC.Utils.Misc
+import GHC.Utils.Outputable
+import System.FilePath (normalise)
+
+--------------------------------------------------------------------------------
+-- Output helpers
+--------------------------------------------------------------------------------
+
+writeJSONFile :: ToJson a => a -> FilePath -> IO ()
+writeJSONFile doc p = do
+ withAtomicRename p
+ $ \tmp -> writeFile tmp $ showSDocUnsafe $ renderJSON $ json doc
+
+--------------------------------------------------------------------------------
+-- Output interface for json dumps
+--------------------------------------------------------------------------------
+
+-- | Resources for a json dump option, used in "GHC.Driver.MakeFile".
+-- The flag @-dep-json@ add an additional output target for dependency
+-- diagnostics.
+data JsonOutput a =
+ JsonOutput {
+ -- | This ref is updated in @processDeps@ incrementally, using a
+ -- flag-specific type.
+ json_ref :: IORef a,
+
+ -- | The output file path specified as argument to the flag.
+ json_path :: FilePath
+ }
+
+-- | Allocate an 'IORef' with the given function if the 'FilePath' is 'Just',
+-- indicating that the userspecified @-*-json@.
+mkJsonOutput ::
+ IO (IORef a) ->
+ Maybe FilePath ->
+ IO (Maybe (JsonOutput a))
+mkJsonOutput mk_ref =
+ traverse $ \ json_path -> do
+ json_ref <- mk_ref
+ pure JsonOutput {json_ref, json_path}
+
+-- | Update the dump data in 'json_ref' if the output target is present.
+updateJson :: Maybe (JsonOutput a) -> (a -> a) -> IO ()
+updateJson out f = traverse_ (\ JsonOutput {json_ref} -> modifyIORef' json_ref f) out
+
+-- | Write a json object to the flag-dependent file if the output target is
+-- present.
+writeJsonOutput ::
+ ToJson a =>
+ Maybe (JsonOutput a) ->
+ IO ()
+writeJsonOutput =
+ traverse_ $ \ JsonOutput {json_ref, json_path} -> do
+ payload <- readIORef json_ref
+ writeJSONFile payload json_path
+
+--------------------------------------------------------------------------------
+-- Types abstracting over json and Makefile
+--------------------------------------------------------------------------------
+
+data DepNode =
+ DepNode {
+ dn_mod :: Module,
+ dn_src :: FilePath,
+ dn_obj :: FilePath,
+ dn_hi :: FilePath,
+ dn_boot :: IsBootInterface,
+ dn_options :: Set.Set String
+ }
+
+data Dep =
+ DepHi {
+ dep_mod :: Module,
+ dep_path :: FilePath,
+ dep_unit :: Maybe UnitInfo,
+ dep_local :: Bool,
+ dep_boot :: IsBootInterface
+ }
+ |
+ DepCpp {
+ dep_path :: FilePath
+ }
+
+--------------------------------------------------------------------------------
+-- Payload for -dep-json
+--------------------------------------------------------------------------------
+
+newtype PackageDeps =
+ PackageDeps (Map.Map (String, UnitId, PackageId) (Set.Set ModuleName))
+ deriving newtype (Monoid)
+
+instance Semigroup PackageDeps where
+ PackageDeps l <> PackageDeps r = PackageDeps (Map.unionWith (Semigroup.<>) l r)
+
+data Deps =
+ Deps {
+ sources :: Set.Set FilePath,
+ modules :: (Set.Set ModuleName, Set.Set ModuleName),
+ packages :: PackageDeps,
+ cpp :: Set.Set FilePath,
+ options :: Set.Set String,
+ preprocessor :: Maybe FilePath
+ }
+ deriving stock (Generic)
+ deriving (Semigroup, Monoid) via (Generically Deps)
+
+newtype DepJSON = DepJSON (Map.Map ModuleName Deps)
+
+instance ToJson DepJSON where
+ json (DepJSON m) =
+ JSObject [
+ (moduleNameString target, JSObject [
+ ("sources", array sources normalise),
+ ("modules", array (fst modules) moduleNameString),
+ ("modules-boot", array (snd modules) moduleNameString),
+ ("packages",
+ JSArray [
+ package name unit_id package_id mods |
+ ((name, unit_id, package_id), mods) <- Map.toList packages
+ ]
+ ),
+ ("cpp", array cpp id),
+ ("options", array options id),
+ ("preprocessor", maybe JSNull JSString preprocessor)
+ ])
+ | (target, Deps {packages = PackageDeps packages, ..}) <- Map.toList m
+ ]
+ where
+ package name unit_id (PackageId package_id) mods =
+ JSObject [
+ ("id", JSString (unitIdString unit_id)),
+ ("name", JSString name),
+ ("package-id", JSString (unpackFS package_id)),
+ ("modules", array mods moduleNameString)
+ ]
+
+ array values render = JSArray (fmap (JSString . render) (Set.toList values))
+
+initDepJSON :: IO (IORef DepJSON)
+initDepJSON = newIORef $ DepJSON Map.empty
+
+insertDepJSON :: [ModuleName] -> Deps -> DepJSON -> DepJSON
+insertDepJSON targets dep (DepJSON m0) =
+ DepJSON
+ $ foldl'
+ ( \acc target ->
+ Map.insertWith
+ (Semigroup.<>)
+ target
+ dep
+ acc
+ )
+ m0
+ targets
+
+updateDepJSON :: Bool -> Maybe FilePath -> DepNode -> [Dep] -> DepJSON -> DepJSON
+updateDepJSON include_pkgs preprocessor DepNode {..} deps =
+ insertDepJSON [moduleName dn_mod] payload
+ where
+ payload = node_data Semigroup.<> foldMap dep deps
+
+ node_data =
+ mempty {
+ sources = Set.singleton dn_src,
+ preprocessor,
+ options = dn_options
+ }
+
+ dep = \case
+ DepHi {dep_mod, dep_local, dep_unit, dep_boot}
+ | dep_local
+ , let set = Set.singleton (moduleName dep_mod)
+ value | IsBoot <- dep_boot = (Set.empty, set)
+ | otherwise = (set, Set.empty)
+ -> mempty {modules = value}
+
+ | include_pkgs
+ , Just unit <- dep_unit
+ , let PackageName nameFS = unitPackageName unit
+ name = unpackFS nameFS
+ withLibName (PackageName c) = name ++ ":" ++ unpackFS c
+ lname = maybe name withLibName (unitComponentName unit)
+ key = (lname, unitId unit, unitPackageId unit)
+ -> mempty {packages = PackageDeps (Map.singleton key (Set.singleton (moduleName dep_mod)))}
+
+ | otherwise
+ -> mempty
+
+ DepCpp {dep_path} ->
+ mempty {cpp = Set.singleton dep_path}
=====================================
compiler/GHC/Driver/Pipeline/Execute.hs
=====================================
@@ -753,6 +753,7 @@ runHscPhase pipe_env hsc_env0 input_fn src_flavour = do
ms_iface_date = hi_date,
ms_hie_date = hie_date,
ms_textual_imps = imps,
+ ms_opts = [],
ms_srcimps = src_imps }
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -753,6 +753,9 @@ addDepExcludeMod m d
addDepSuffix :: FilePath -> DynFlags -> DynFlags
addDepSuffix s d = d { depSuffixes = s : depSuffixes d }
+setDepJSON :: FilePath -> DynFlags -> DynFlags
+setDepJSON f d = d { depJSON = Just f }
+
addCmdlineFramework f d = d { cmdlineFrameworks = f : cmdlineFrameworks d}
addGhcVersionFile :: FilePath -> DynFlags -> DynFlags
@@ -1218,6 +1221,7 @@ dynamic_flags_deps = [
, make_ord_flag defGhcFlag "include-pkg-deps"
(noArg (setDepIncludePkgDeps True))
, make_ord_flag defGhcFlag "exclude-module" (hasArg addDepExcludeMod)
+ , make_ord_flag defGhcFlag "dep-json" (hasArg setDepJSON)
-------- Linking ----------------------------------------------------
, make_ord_flag defGhcFlag "no-link"
=====================================
compiler/GHC/Unit/Info.hs
=====================================
@@ -117,6 +117,9 @@ instance Outputable PackageId where
instance Outputable PackageName where
ppr (PackageName str) = ftext str
+instance Ord PackageId where
+ PackageId p1 `compare` PackageId p2 = p1 `lexicalCompareFS` p2
+
unitPackageIdString :: GenUnitInfo u -> String
unitPackageIdString pkg = unpackFS str
where
=====================================
compiler/GHC/Unit/Module/ModSummary.hs
=====================================
@@ -83,6 +83,8 @@ data ModSummary
-- ^ Source imports of the module
ms_textual_imps :: [(PkgQual, Located ModuleName)],
-- ^ Non-source imports of the module from the module *text*
+ ms_opts :: ![String],
+ -- ^ OPTIONS and LANGUAGE pragmas of the source file
ms_parsed_mod :: Maybe HsParsedModule,
-- ^ The parsed, nonrenamed source, if we have it. This is also
-- used to support "inline module syntax" in Backpack files.
=====================================
compiler/GHC/Unit/State.hs
=====================================
@@ -71,6 +71,7 @@ module GHC.Unit.State (
unwireUnit)
where
+import Data.Foldable (find)
import GHC.Prelude
import GHC.Driver.DynFlags
@@ -903,8 +904,18 @@ applyPackageFlag prec_map pkg_map closure unusable no_hide_others pkgs vm flag =
ExposePackage _ arg (ModRenaming b rns) ->
case findPackages prec_map pkg_map closure arg pkgs unusable of
Left ps -> Failed (PackageFlagErr flag ps)
- Right (p:_) -> Succeeded vm'
+ Right ps@(p0:_) -> Succeeded vm'
where
+ p | PackageArg _ <- arg = fromMaybe p0 mainPackage
+ | otherwise = p0
+
+ mainPackage = find (\ u -> isNothing (unitComponentName u)) matchFirst
+
+ matchFirst = filter (\ u -> unitPackageName u == firstName && unitPackageVersion u == firstVersion) ps
+
+ firstName = unitPackageName p0
+ firstVersion = unitPackageVersion p0
+
n = fsPackageName p
-- If a user says @-unit-id p[A=<A>]@, this imposes
@@ -1030,6 +1041,13 @@ matchingStr :: String -> UnitInfo -> Bool
matchingStr str p
= str == unitPackageIdString p
|| str == unitPackageNameString p
+ || matchSublibrary
+ where
+ matchSublibrary
+ | Just (PackageName c) <- unitComponentName p
+ = str == (unitPackageNameString p ++ ":" ++ unpackFS c)
+ | otherwise
+ = False
matchingId :: UnitId -> UnitInfo -> Bool
matchingId uid p = uid == unitId p
=====================================
compiler/ghc.cabal.in
=====================================
@@ -528,6 +528,7 @@ Library
GHC.Driver.Make
GHC.Driver.MakeAction
GHC.Driver.MakeFile
+ GHC.Driver.MakeFile.JSON
GHC.Driver.Monad
GHC.Driver.Phases
GHC.Driver.Pipeline
=====================================
configure.ac
=====================================
@@ -13,7 +13,7 @@ dnl
# see what flags are available. (Better yet, read the documentation!)
#
-AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.13], [glasgow-haskell-bugs(a)haskell.org] [ghc-AC_PACKAGE_VERSION])
+AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.12.1], [glasgow-haskell-bugs(a)haskell.org] [ghc-AC_PACKAGE_VERSION])
# Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable
# to be useful (cf #19058). However, the version must have three components
# (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are
@@ -22,7 +22,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.13], [glasgow-hask
AC_CONFIG_MACRO_DIRS([m4])
# Set this to YES for a released version, otherwise NO
-: ${RELEASE=NO}
+: ${RELEASE=YES}
# The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line
# above. If this is not a released version, then we will append the
=====================================
docs/users_guide/separate_compilation.rst
=====================================
@@ -1520,6 +1520,22 @@ generation are:
is only a temporary file that GHC will always generate, it is not output as
a dependency.
+.. ghc-flag:: -dep-json ⟨file⟩
+ :shortdesc: Also emit ⟨file⟩ as a JSON file containing dependencies
+ :type: dynamic
+ :category: redirect-output
+
+ In addition to the makefile, also emit ⟨file⟩ as a JSON file
+ containing the same dependencies info, so it can be parsed by
+ external build systems. The JSON file contains a single object,
+ mapping each target to a list of dependencies.
+ In addition to the makefile, each module's payload will contain the
+ values of ``OPTIONS`` and ``LANGUAGE`` pragmas of the source
+ file, so it can be parsed by external build systems. Each ``LANGUAGE``
+ pragma is represented as an option as well, e.g.
+ ``{-# LANGUAGE TemplateHaskell #-}`` is represented as
+ ``"-XTemplateHaskell"``.
+
.. _orphan-modules:
Orphan modules and instance declarations
=====================================
docs/users_guide/using.rst
=====================================
@@ -366,7 +366,7 @@ The available mode flags are:
.. ghc-flag:: -M
:shortdesc: generate dependency information suitable for use in a
- ``Makefile``; see :ref:`makefile-dependencies` for details.
+ ``Makefile`` or as JSON; see :ref:`makefile-dependencies` for details.
:type: mode
:category: modes
=====================================
testsuite/tests/driver/T24384/A.hs
=====================================
@@ -0,0 +1,5 @@
+{-# language Strict #-}
+{-# options_ghc -fexpose-all-unfoldings #-}
+module A where
+
+import {-# source #-} C
=====================================
testsuite/tests/driver/T24384/B.hs
=====================================
@@ -0,0 +1,2 @@
+{-# options_ghc -F -pgmF ./preproc.sh #-}
+module B where
=====================================
testsuite/tests/driver/T24384/C.hs
=====================================
@@ -0,0 +1,6 @@
+module C where
+
+import A
+import Data.Set
+
+data C = C
=====================================
testsuite/tests/driver/T24384/C.hs-boot
=====================================
@@ -0,0 +1,5 @@
+module C where
+
+import E
+
+data C
=====================================
testsuite/tests/driver/T24384/D.hs
=====================================
@@ -0,0 +1,4 @@
+module D where
+
+import B
+import C
=====================================
testsuite/tests/driver/T24384/E.hs
=====================================
@@ -0,0 +1,14 @@
+module E where
+
+import Language.Haskell.TH.Syntax
+import Dep
+import DepPub
+
+e :: Q Exp
+e = lift (5 :: Integer)
+
+edep :: ()
+edep = dep
+
+edepPub :: ()
+edepPub = depPub
=====================================
testsuite/tests/driver/T24384/Makefile
=====================================
@@ -0,0 +1,10 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+T24384:
+ ./setup-dep.sh "$(TEST_HC)" "$(TEST_HC_OPTS)" "$(CABAL_MINIMAL_BUILD)" "$(GHC_PKG)"
+ mkdir -p lib
+ mv B.hs lib/
+ '$(TEST_HC)' A.hs lib/B.hs C.hs D.hs E.hs -M -dep-json dep.json -include-pkg-deps -include-cpp-deps -package-db ./db -hide-all-packages -package base -package containers -package template-haskell -package dep -package dep:pub
+ cat dep.json
=====================================
testsuite/tests/driver/T24384/T24384.stdout
=====================================
@@ -0,0 +1 @@
+{"A":{"sources":["A.hs"],"modules":[],"modules-boot":["C"],"packages":[{"id":"base","name":"base","package-id":"base-4.20.0.0","modules":["Prelude"]}],"cpp":[],"options":["-XStrict","-fexpose-all-unfoldings"],"preprocessor":null},"B":{"sources":["lib/B.hs"],"modules":["A"],"modules-boot":[],"packages":[{"id":"base","name":"base","package-id":"base-4.20.0.0","modules":["Prelude"]}],"cpp":[],"options":[],"preprocessor":"./preproc.sh"},"C":{"sources":["C.hs","C.hs-boot"],"modules":["A","E"],"modules-boot":[],"packages":[{"id":"base","name":"base","package-id":"base-4.20.0.0","modules":["Prelude"]},{"id":"containers-0.7-inplace","name":"containers","package-id":"containers-0.7","modules":["Data.Set"]}],"cpp":[],"options":[],"preprocessor":null},"D":{"sources":["D.hs"],"modules":["B","C"],"modules-boot":[],"packages":[{"id":"base","name":"base","package-id":"base-4.20.0.0","modules":["Prelude"]}],"cpp":[],"options":[],"preprocessor":null},"E":{"sources":["E.hs"],"modules":[],"modules-boot":[],"packages":[{"id":"base","name":"base","package-id":"base-4.20.0.0","modules":["Prelude"]},{"id":"dep-1-Acdff5K3xp09fO6uiTrnge","name":"dep","package-id":"dep-1","modules":["Dep"]},{"id":"dep-1-8mhA0yJkyEn42CuhdNx93G-pub","name":"dep:pub","package-id":"dep-1","modules":["DepPub"]},{"id":"template-haskell","name":"template-haskell","package-id":"template-haskell-2.22.0.0","modules":["Language.Haskell.TH.Syntax"]}],"cpp":[],"options":[],"preprocessor":null}}
\ No newline at end of file
=====================================
testsuite/tests/driver/T24384/all.T
=====================================
@@ -0,0 +1 @@
+test('T24384', [extra_files(['A.hs', 'B.hs', 'C.hs', 'C.hs-boot', 'D.hs', 'E.hs', 'preproc.sh', 'setup-dep.sh'])], makefile_test, [])
=====================================
testsuite/tests/driver/T24384/preproc.sh
=====================================
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+sed '/preproc/d' $2 > $3
+echo 'import A' >> $3
=====================================
testsuite/tests/driver/T24384/setup-dep.sh
=====================================
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+
+set -eu
+
+ghc="$1"
+ghc_opts="$2"
+config_options="$3"
+ghc_pkg="$4"
+base=$(cd $(dirname $0); pwd)
+
+mkdir -p dep/{int,pub}
+$ghc_pkg init ./db
+
+cd dep/
+
+cat > dep.cabal <<EOF
+cabal-version: 3.4
+name: dep
+version: 1
+build-type: Simple
+library
+ default-language: Haskell2010
+ exposed-modules: Dep
+ build-depends: base, dep:int
+library int
+ default-language: Haskell2010
+ hs-source-dirs: int
+ exposed-modules: DepInt
+ build-depends: base
+library pub
+ default-language: Haskell2010
+ hs-source-dirs: pub
+ visibility: public
+ exposed-modules: DepPub
+ build-depends: base
+EOF
+
+cat > Dep.hs <<EOF
+module Dep where
+import DepInt
+dep :: ()
+dep = depInt
+EOF
+
+cat > int/DepInt.hs <<EOF
+module DepInt where
+depInt :: ()
+depInt = ()
+EOF
+
+cat > pub/DepPub.hs <<EOF
+module DepPub where
+depPub :: ()
+depPub = ()
+EOF
+
+cat > Setup.hs <<EOF
+import Distribution.Simple
+main = defaultMain
+EOF
+
+eval $ghc $ghc_opts -v0 --make Setup
+eval ./Setup configure $config_options --with-ghc="'$ghc'" --with-hc-pkg="'$ghc_pkg'" --ghc-options="'$ghc_opts'" --package-db="'$base/db'" -v0
+./Setup build -v0
+./Setup register --inplace -v0
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0695c6d47d7e517be6f125fb5e1b3e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/0695c6d47d7e517be6f125fb5e1b3e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/torsten.schmits/mercury-fixed] 2 commits: driver: add -dep-json -opt-json flags to ghc -M
by Torsten Schmits (@torsten.schmits) 22 Oct '25
by Torsten Schmits (@torsten.schmits) 22 Oct '25
22 Oct '25
Torsten Schmits pushed to branch wip/torsten.schmits/mercury-fixed at Glasgow Haskell Compiler / GHC
Commits:
7e8c1a07 by Cheng Shao at 2025-10-22T15:25:13+02:00
driver: add -dep-json -opt-json flags to ghc -M
docs: document -dep-json -opt-json flags
Rework protocol
merge opt-json into dep-json
normalize source filenames
include more canonical variant of the package id
choose the main library when -package matches multiple units with the same version
allow specifying library deps with -package pkg:lib
Backported to GHC 9.10
- - - - -
0695c6d4 by Torsten Schmits at 2025-10-22T15:25:13+02:00
release
- - - - -
25 changed files:
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/MakeFile.hs
- + compiler/GHC/Driver/MakeFile/JSON.hs
- compiler/GHC/Driver/Pipeline/Execute.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/Module/ModSummary.hs
- compiler/GHC/Unit/State.hs
- compiler/ghc.cabal.in
- configure.ac
- docs/users_guide/separate_compilation.rst
- docs/users_guide/using.rst
- + testsuite/tests/driver/T24384/A.hs
- + testsuite/tests/driver/T24384/B.hs
- + testsuite/tests/driver/T24384/C.hs
- + testsuite/tests/driver/T24384/C.hs-boot
- + testsuite/tests/driver/T24384/D.hs
- + testsuite/tests/driver/T24384/E.hs
- + testsuite/tests/driver/T24384/Makefile
- + testsuite/tests/driver/T24384/T24384.stdout
- + testsuite/tests/driver/T24384/all.T
- + testsuite/tests/driver/T24384/preproc.sh
- + testsuite/tests/driver/T24384/setup-dep.sh
Changes:
=====================================
compiler/GHC/Driver/Backpack.hs
=====================================
@@ -804,6 +804,7 @@ summariseRequirement pn mod_name = do
ms_hie_date = hie_timestamp,
ms_srcimps = [],
ms_textual_imps = ((,) NoPkgQual . noLoc) <$> extra_sig_imports,
+ ms_opts = [],
ms_parsed_mod = Just (HsParsedModule {
hpm_module = L loc (HsModule {
hsmodExt = XModulePs {
@@ -909,6 +910,7 @@ hsModuleToModSummary home_keys pn hsc_src modname
-- extra imports
++ ((,) NoPkgQual . noLoc <$> extra_sig_imports)
++ ((,) NoPkgQual . noLoc <$> implicit_sigs),
+ ms_opts = [],
-- This is our hack to get the parse tree to the right spot
ms_parsed_mod = Just (HsParsedModule {
hpm_module = hsmod,
=====================================
compiler/GHC/Driver/Downsweep.hs
=====================================
@@ -27,7 +27,7 @@ import GHC.Tc.Utils.Backpack
import GHC.Platform.Ways
import GHC.Driver.Config.Finder (initFinderOpts)
-import GHC.Driver.Config.Parser (initParserOpts)
+import GHC.Driver.Config.Parser (initParserOpts, supportedLanguagePragmas)
import GHC.Driver.Phases
import GHC.Driver.Pipeline
import GHC.Driver.Session
@@ -819,6 +819,7 @@ summariseFile hsc_env' home_unit old_summaries src_fn mb_phase maybe_buf
, nms_location = location
, nms_mod = mod
, nms_preimps = preimps
+ , nms_opts = pi_mod_opts
}
checkSummaryHash
@@ -981,6 +982,7 @@ summariseModule hsc_env' home_unit old_summary_map is_boot (L _ wanted_mod) mb_p
, nms_location = location
, nms_mod = mod
, nms_preimps = preimps
+ , nms_opts = pi_mod_opts
}
-- | Convenience named arguments for 'makeNewModSummary' only used to make
@@ -993,6 +995,7 @@ data MakeNewModSummary
, nms_location :: ModLocation
, nms_mod :: Module
, nms_preimps :: PreprocessedImports
+ , nms_opts :: ![String]
}
makeNewModSummary :: HscEnv -> MakeNewModSummary -> IO ModSummary
@@ -1020,6 +1023,7 @@ makeNewModSummary hsc_env MakeNewModSummary{..} = do
((,) NoPkgQual . noLoc <$> extra_sig_imports) ++
((,) NoPkgQual . noLoc <$> implicit_sigs) ++
pi_theimps
+ , ms_opts = nms_opts
, ms_hs_hash = nms_src_hash
, ms_iface_date = hi_timestamp
, ms_hie_date = hie_timestamp
@@ -1036,6 +1040,7 @@ data PreprocessedImports
, pi_hspp_buf :: StringBuffer
, pi_mod_name_loc :: SrcSpan
, pi_mod_name :: ModuleName
+ , pi_mod_opts :: ![String]
}
-- Preprocess the source file and get its imports
@@ -1051,14 +1056,15 @@ getPreprocessedImports hsc_env src_fn mb_phase maybe_buf = do
(pi_local_dflags, pi_hspp_fn)
<- ExceptT $ preprocess hsc_env src_fn (fst <$> maybe_buf) mb_phase
pi_hspp_buf <- liftIO $ hGetStringBuffer pi_hspp_fn
- (pi_srcimps', pi_theimps', L pi_mod_name_loc pi_mod_name)
+ ((pi_srcimps', pi_theimps', L pi_mod_name_loc pi_mod_name), pi_mod_opts)
<- ExceptT $ do
let imp_prelude = xopt LangExt.ImplicitPrelude pi_local_dflags
popts = initParserOpts pi_local_dflags
mimps <- getImports popts imp_prelude pi_hspp_buf pi_hspp_fn src_fn
- return (first (mkMessages . fmap mkDriverPsHeaderMessage . getMessages) mimps)
+ let mopts = map unLoc $ snd $ getOptions popts (supportedLanguagePragmas pi_local_dflags) pi_hspp_buf src_fn
+ pure $ ((, mopts) <$>) $ first (mkMessages . fmap mkDriverPsHeaderMessage . getMessages) mimps
let rn_pkg_qual = renameRawPkgQual (hsc_unit_env hsc_env)
let rn_imps = fmap (\(pk, lmn@(L _ mn)) -> (rn_pkg_qual mn pk, lmn))
let pi_srcimps = rn_imps pi_srcimps'
let pi_theimps = rn_imps pi_theimps'
- return PreprocessedImports {..}
\ No newline at end of file
+ return PreprocessedImports {..}
=====================================
compiler/GHC/Driver/DynFlags.hs
=====================================
@@ -338,6 +338,7 @@ data DynFlags = DynFlags {
depIncludeCppDeps :: Bool,
depExcludeMods :: [ModuleName],
depSuffixes :: [String],
+ depJSON :: !(Maybe FilePath),
-- Package flags
packageDBFlags :: [PackageDBFlag],
@@ -667,6 +668,7 @@ defaultDynFlags mySettings =
depIncludeCppDeps = False,
depExcludeMods = [],
depSuffixes = [],
+ depJSON = Nothing,
-- end of ghc -M values
ghcVersionFile = Nothing,
haddockOptions = Nothing,
=====================================
compiler/GHC/Driver/MakeFile.hs
=====================================
@@ -1,4 +1,5 @@
-
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE NamedFieldPuns #-}
-----------------------------------------------------------------------------
--
@@ -17,12 +18,19 @@ where
import GHC.Prelude
import qualified GHC
+import GHC.Data.Maybe
import GHC.Driver.Make
import GHC.Driver.Monad
import GHC.Driver.DynFlags
+import GHC.Driver.Ppr
+import GHC.Driver.MakeFile.JSON
import GHC.Utils.Misc
import GHC.Driver.Env
import GHC.Driver.Errors.Types
+import GHC.Driver.Pipeline (runPipeline, TPhase (T_Unlit, T_FileArgs), use, mkPipeEnv)
+import GHC.Driver.Phases (StopPhase (StopPreprocess), startPhase, Phase (Unlit))
+import GHC.Driver.Pipeline.Monad (PipelineOutput (NoOutputFile))
+import GHC.Driver.Session (pgm_F)
import qualified GHC.SysTools as SysTools
import GHC.Data.Graph.Directed ( SCC(..) )
import GHC.Data.OsPath (unsafeDecodeUtf)
@@ -35,11 +43,13 @@ import Data.List (partition)
import GHC.Utils.TmpFs
import GHC.Iface.Load (cannotFindModule)
+import GHC.Iface.Errors.Types
import GHC.Unit.Module
import GHC.Unit.Module.ModSummary
import GHC.Unit.Module.Graph
import GHC.Unit.Finder
+import GHC.Unit.State (lookupUnitId)
import GHC.Utils.Exception
import GHC.Utils.Error
@@ -49,8 +59,8 @@ import System.Directory
import System.FilePath
import System.IO
import System.IO.Error ( isEOFError )
-import Control.Monad ( when, forM_ )
-import Data.Maybe ( isJust )
+import Control.Monad ( when )
+import Data.Foldable (traverse_)
import Data.IORef
import qualified Data.Set as Set
import GHC.Iface.Errors.Types
@@ -110,7 +120,7 @@ doMkDependModuleGraph dflags module_graph = do
-- and complaining about cycles
hsc_env <- getSession
root <- liftIO getCurrentDirectory
- mapM_ (liftIO . processDeps dflags hsc_env excl_mods root (mkd_tmp_hdl files)) sorted
+ mapM_ (liftIO . processDeps dflags hsc_env excl_mods root (mkd_tmp_hdl files) (mkd_dep_json files)) sorted
-- If -ddump-mod-cycles, show cycles in the module graph
liftIO $ dumpModCycles logger module_graph
@@ -118,13 +128,6 @@ doMkDependModuleGraph dflags module_graph = do
-- Tidy up
liftIO $ endMkDependHS logger files
- -- Unconditional exiting is a bad idea. If an error occurs we'll get an
- --exception; if that is not caught it's fine, but at least we have a
- --chance to find out exactly what went wrong. Uncomment the following
- --line if you disagree.
-
- --`GHC.ghcCatch` \_ -> io $ exitWith (ExitFailure 1)
-
-----------------------------------------------------------------
--
-- beginMkDependHs
@@ -137,6 +140,8 @@ doMkDependModuleGraph dflags module_graph = do
data MkDepFiles
= MkDep { mkd_make_file :: FilePath, -- Name of the makefile
mkd_make_hdl :: Maybe Handle, -- Handle for the open makefile
+ -- | Output interface for the -dep-json file
+ mkd_dep_json :: !(Maybe (JsonOutput DepJSON)),
mkd_tmp_file :: FilePath, -- Name of the temporary file
mkd_tmp_hdl :: Handle } -- Handle of the open temporary file
@@ -179,14 +184,15 @@ beginMkDependHS logger tmpfs dflags = do
return (Just makefile_hdl)
+ dep_json_ref <- mkJsonOutput initDepJSON (depJSON dflags)
-- write the magic marker into the tmp file
hPutStrLn tmp_hdl depStartMarker
return (MkDep { mkd_make_file = makefile, mkd_make_hdl = mb_make_hdl,
+ mkd_dep_json = dep_json_ref,
mkd_tmp_file = tmp_file, mkd_tmp_hdl = tmp_hdl})
-
-----------------------------------------------------------------
--
-- processDeps
@@ -198,6 +204,7 @@ processDeps :: DynFlags
-> [ModuleName]
-> FilePath
-> Handle -- Write dependencies to here
+ -> Maybe (JsonOutput DepJSON)
-> SCC ModuleGraphNode
-> IO ()
-- Write suitable dependencies to handle
@@ -230,64 +237,68 @@ processDeps _dflags _ _ _ _ (AcyclicSCC (UnitNode {})) = return ()
processDeps _ _ _ _ _ (AcyclicSCC (ModuleNode _ (ModuleNodeFixed {})))
-- No dependencies needed for fixed modules (already compiled)
= return ()
-processDeps dflags hsc_env excl_mods root hdl (AcyclicSCC (ModuleNode _ (ModuleNodeCompile node)))
- = do { let extra_suffixes = depSuffixes dflags
- include_pkg_deps = depIncludePkgDeps dflags
- src_file = msHsFilePath node
- obj_file = msObjFilePath node
- obj_files = insertSuffixes obj_file extra_suffixes
-
- do_imp loc is_boot pkg_qual imp_mod
- = do { mb_hi <- findDependency hsc_env loc pkg_qual imp_mod
- is_boot include_pkg_deps
- ; case mb_hi of {
- Nothing -> return () ;
- Just hi_file -> do
- { let hi_files = insertSuffixes hi_file extra_suffixes
- write_dep (obj,hi) = writeDependency root hdl [obj] hi
-
- -- Add one dependency for each suffix;
- -- e.g. A.o : B.hi
- -- A.x_o : B.x_hi
- ; mapM_ write_dep (obj_files `zip` hi_files) }}}
-
-
- -- Emit std dependency of the object(s) on the source file
- -- Something like A.o : A.hs
- ; writeDependency root hdl obj_files src_file
-
- -- add dependency between objects and their corresponding .hi-boot
- -- files if the module has a corresponding .hs-boot file (#14482)
- ; when (isBootSummary node == IsBoot) $ do
- let hi_boot = msHiFilePath node
- let obj = unsafeDecodeUtf $ removeBootSuffix (msObjFileOsPath node)
- forM_ extra_suffixes $ \suff -> do
- let way_obj = insertSuffixes obj [suff]
- let way_hi_boot = insertSuffixes hi_boot [suff]
- mapM_ (writeDependency root hdl way_obj) way_hi_boot
-
- -- Emit a dependency for each CPP import
- ; when (depIncludeCppDeps dflags) $ do
- -- CPP deps are discovered in the module parsing phase by parsing
- -- comment lines left by the preprocessor.
- -- Note that GHC.parseModule may throw an exception if the module
- -- fails to parse, which may not be desirable (see #16616).
- { session <- Session <$> newIORef hsc_env
- ; parsedMod <- reflectGhc (GHC.parseModule node) session
- ; mapM_ (writeDependency root hdl obj_files)
- (GHC.pm_extra_src_files parsedMod)
- }
-
- -- Emit a dependency for each import
-
- ; let do_imps is_boot idecls = sequence_
- [ do_imp loc is_boot mb_pkg mod
- | (mb_pkg, L loc mod) <- idecls,
- mod `notElem` excl_mods ]
-
- ; do_imps IsBoot (ms_srcimps node)
- ; do_imps NotBoot (ms_imps node)
- }
+
+processDeps dflags hsc_env excl_mods root hdl m_dep_json (AcyclicSCC (ModuleNode _ (ModuleNodeCompile _ node))) = do
+ pp <- preprocessor
+ deps <- fmap concat $ sequence $
+ [cpp_deps | depIncludeCppDeps dflags] ++ [
+ import_deps IsBoot (ms_srcimps node),
+ import_deps NotBoot (ms_imps node)
+ ]
+ updateJson m_dep_json (updateDepJSON include_pkg_deps pp dep_node deps)
+ writeDependencies include_pkg_deps root hdl extra_suffixes dep_node deps
+ where
+ extra_suffixes = depSuffixes dflags
+ include_pkg_deps = depIncludePkgDeps dflags
+ src_file = msHsFilePath node
+ dep_node =
+ DepNode {
+ dn_mod = ms_mod node,
+ dn_src = src_file,
+ dn_obj = msObjFilePath node,
+ dn_hi = msHiFilePath node,
+ dn_boot = isBootSummary node,
+ dn_options = Set.fromList (ms_opts node)
+ }
+
+ preprocessor
+ | Just src <- ml_hs_file (ms_location node)
+ = runPipeline (hsc_hooks hsc_env) $ do
+ let (_, suffix) = splitExtension src
+ lit | Unlit _ <- startPhase suffix = True
+ | otherwise = False
+ pipe_env = mkPipeEnv StopPreprocess src Nothing NoOutputFile
+ unlit_fn <- if lit then use (T_Unlit pipe_env hsc_env src) else pure src
+ (dflags1, _, _) <- use (T_FileArgs hsc_env unlit_fn)
+ let pp = pgm_F dflags1
+ pure (if null pp then global_preprocessor else Just pp)
+ | otherwise
+ = pure global_preprocessor
+
+ global_preprocessor
+ | let pp = pgm_F dflags
+ , not (null pp)
+ = Just pp
+ | otherwise
+ = Nothing
+
+ -- Emit a dependency for each CPP import
+ -- CPP deps are discovered in the module parsing phase by parsing
+ -- comment lines left by the preprocessor.
+ -- Note that GHC.parseModule may throw an exception if the module
+ -- fails to parse, which may not be desirable (see #16616).
+ cpp_deps = do
+ session <- Session <$> newIORef hsc_env
+ parsedMod <- reflectGhc (GHC.parseModule node) session
+ pure (DepCpp <$> GHC.pm_extra_src_files parsedMod)
+
+ -- Emit a dependency for each import
+ import_deps is_boot idecls =
+ sequence [
+ findDependency hsc_env loc mb_pkg mod is_boot
+ | (mb_pkg, L loc mod) <- idecls
+ , mod `notElem` excl_mods
+ ]
findDependency :: HscEnv
@@ -295,27 +306,76 @@ findDependency :: HscEnv
-> PkgQual -- package qualifier, if any
-> ModuleName -- Imported module
-> IsBootInterface -- Source import
- -> Bool -- Record dependency on package modules
- -> IO (Maybe FilePath) -- Interface file
-findDependency hsc_env srcloc pkg imp is_boot include_pkg_deps = do
+ -> IO Dep
+findDependency hsc_env srcloc pkg imp dep_boot = do
-- Find the module; this will be fast because
-- we've done it once during downsweep
- r <- findImportedModuleWithIsBoot hsc_env imp is_boot pkg
- case r of
- Found loc _
- -- Home package: just depend on the .hi or hi-boot file
- | isJust (ml_hs_file loc) || include_pkg_deps
- -> return (Just (ml_hi_file loc))
-
- -- Not in this package: we don't need a dependency
- | otherwise
- -> return Nothing
+ findImportedModule hsc_env imp pkg >>= \case
+ Found loc dep_mod ->
+ pure DepHi {
+ dep_mod,
+ dep_path = ml_hi_file loc,
+ dep_unit = lookupUnitId (hsc_units hsc_env) (moduleUnitId dep_mod),
+ dep_local,
+ dep_boot
+ }
+ where
+ dep_local = isJust (ml_hs_file loc)
fail ->
- throwOneError $
- mkPlainErrorMsgEnvelope srcloc $
- GhcDriverMessage $ DriverInterfaceError $
- (Can'tFindInterface (cannotFindModule hsc_env imp fail) (LookingForModule imp is_boot))
+ throwOneError $
+ mkPlainErrorMsgEnvelope srcloc $
+ GhcDriverMessage $
+ DriverInterfaceError $
+ Can'tFindInterface (cannotFindModule hsc_env imp fail) $
+ LookingForModule imp dep_boot
+
+writeDependencies ::
+ Bool ->
+ FilePath ->
+ Handle ->
+ [FilePath] ->
+ DepNode ->
+ [Dep] ->
+ IO ()
+writeDependencies include_pkgs root hdl suffixes node deps =
+ traverse_ write tasks
+ where
+ tasks = source_dep : boot_dep ++ concatMap import_dep deps
+
+ -- Emit std dependency of the object(s) on the source file
+ -- Something like A.o : A.hs
+ source_dep = (obj_files, dn_src)
+
+ -- add dependency between objects and their corresponding .hi-boot
+ -- files if the module has a corresponding .hs-boot file (#14482)
+ boot_dep
+ | IsBoot <- dn_boot
+ = [([obj], hi) | (obj, hi) <- zip (suffixed (removeBootSuffix dn_obj)) (suffixed dn_hi)]
+ | otherwise
+ = []
+
+ -- Add one dependency for each suffix;
+ -- e.g. A.o : B.hi
+ -- A.x_o : B.x_hi
+ import_dep = \case
+ DepHi {dep_path, dep_boot, dep_unit}
+ | isNothing dep_unit || include_pkgs
+ , let path = addBootSuffix_maybe dep_boot dep_path
+ -> [([obj], hi) | (obj, hi) <- zip obj_files (suffixed path)]
+
+ | otherwise
+ -> []
+
+ DepCpp {dep_path} -> [(obj_files, dep_path)]
+
+ write (from, to) = writeDependency root hdl from to
+
+ obj_files = suffixed dn_obj
+
+ suffixed f = insertSuffixes f suffixes
+
+ DepNode {dn_src, dn_obj, dn_hi, dn_boot} = node
-----------------------------
writeDependency :: FilePath -> Handle -> [FilePath] -> FilePath -> IO ()
@@ -357,8 +417,9 @@ insertSuffixes file_name extras
endMkDependHS :: Logger -> MkDepFiles -> IO ()
endMkDependHS logger
- (MkDep { mkd_make_file = makefile, mkd_make_hdl = makefile_hdl,
- mkd_tmp_file = tmp_file, mkd_tmp_hdl = tmp_hdl })
+ (MkDep { mkd_make_file = makefile, mkd_make_hdl = makefile_hdl,
+ mkd_dep_json,
+ mkd_tmp_file = tmp_file, mkd_tmp_hdl = tmp_hdl })
= do
-- write the magic marker into the tmp file
hPutStrLn tmp_hdl depEndMarker
@@ -381,6 +442,10 @@ endMkDependHS logger
showPass logger "Installing new makefile"
SysTools.copyFile tmp_file makefile
+ -- Write the dependency and option data to a json file if the corresponding
+ -- flags were specified.
+ writeJsonOutput mkd_dep_json
+
-----------------------------------------------------------------
-- Module cycles
=====================================
compiler/GHC/Driver/MakeFile/JSON.hs
=====================================
@@ -0,0 +1,221 @@
+{-# LANGUAGE DeriveGeneric #-}
+{-# LANGUAGE DerivingVia #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE NamedFieldPuns #-}
+{-# LANGUAGE NoFieldSelectors #-}
+{-# LANGUAGE RecordWildCards #-}
+module GHC.Driver.MakeFile.JSON
+ ( writeJSONFile,
+ JsonOutput (..),
+ mkJsonOutput,
+ updateJson,
+ writeJsonOutput,
+ DepJSON,
+ DepNode (..),
+ Dep (..),
+ initDepJSON,
+ updateDepJSON,
+ )
+where
+
+import Data.Foldable (traverse_)
+import Data.IORef
+import qualified Data.Map.Strict as Map
+import qualified Data.Semigroup as Semigroup
+import qualified Data.Set as Set
+import GHC.Data.FastString (unpackFS)
+import GHC.Generics (Generic, Generically (Generically))
+import GHC.Prelude
+import GHC.Unit
+import GHC.Utils.Json
+import GHC.Utils.Misc
+import GHC.Utils.Outputable
+import System.FilePath (normalise)
+
+--------------------------------------------------------------------------------
+-- Output helpers
+--------------------------------------------------------------------------------
+
+writeJSONFile :: ToJson a => a -> FilePath -> IO ()
+writeJSONFile doc p = do
+ withAtomicRename p
+ $ \tmp -> writeFile tmp $ showSDocUnsafe $ renderJSON $ json doc
+
+--------------------------------------------------------------------------------
+-- Output interface for json dumps
+--------------------------------------------------------------------------------
+
+-- | Resources for a json dump option, used in "GHC.Driver.MakeFile".
+-- The flag @-dep-json@ add an additional output target for dependency
+-- diagnostics.
+data JsonOutput a =
+ JsonOutput {
+ -- | This ref is updated in @processDeps@ incrementally, using a
+ -- flag-specific type.
+ json_ref :: IORef a,
+
+ -- | The output file path specified as argument to the flag.
+ json_path :: FilePath
+ }
+
+-- | Allocate an 'IORef' with the given function if the 'FilePath' is 'Just',
+-- indicating that the userspecified @-*-json@.
+mkJsonOutput ::
+ IO (IORef a) ->
+ Maybe FilePath ->
+ IO (Maybe (JsonOutput a))
+mkJsonOutput mk_ref =
+ traverse $ \ json_path -> do
+ json_ref <- mk_ref
+ pure JsonOutput {json_ref, json_path}
+
+-- | Update the dump data in 'json_ref' if the output target is present.
+updateJson :: Maybe (JsonOutput a) -> (a -> a) -> IO ()
+updateJson out f = traverse_ (\ JsonOutput {json_ref} -> modifyIORef' json_ref f) out
+
+-- | Write a json object to the flag-dependent file if the output target is
+-- present.
+writeJsonOutput ::
+ ToJson a =>
+ Maybe (JsonOutput a) ->
+ IO ()
+writeJsonOutput =
+ traverse_ $ \ JsonOutput {json_ref, json_path} -> do
+ payload <- readIORef json_ref
+ writeJSONFile payload json_path
+
+--------------------------------------------------------------------------------
+-- Types abstracting over json and Makefile
+--------------------------------------------------------------------------------
+
+data DepNode =
+ DepNode {
+ dn_mod :: Module,
+ dn_src :: FilePath,
+ dn_obj :: FilePath,
+ dn_hi :: FilePath,
+ dn_boot :: IsBootInterface,
+ dn_options :: Set.Set String
+ }
+
+data Dep =
+ DepHi {
+ dep_mod :: Module,
+ dep_path :: FilePath,
+ dep_unit :: Maybe UnitInfo,
+ dep_local :: Bool,
+ dep_boot :: IsBootInterface
+ }
+ |
+ DepCpp {
+ dep_path :: FilePath
+ }
+
+--------------------------------------------------------------------------------
+-- Payload for -dep-json
+--------------------------------------------------------------------------------
+
+newtype PackageDeps =
+ PackageDeps (Map.Map (String, UnitId, PackageId) (Set.Set ModuleName))
+ deriving newtype (Monoid)
+
+instance Semigroup PackageDeps where
+ PackageDeps l <> PackageDeps r = PackageDeps (Map.unionWith (Semigroup.<>) l r)
+
+data Deps =
+ Deps {
+ sources :: Set.Set FilePath,
+ modules :: (Set.Set ModuleName, Set.Set ModuleName),
+ packages :: PackageDeps,
+ cpp :: Set.Set FilePath,
+ options :: Set.Set String,
+ preprocessor :: Maybe FilePath
+ }
+ deriving stock (Generic)
+ deriving (Semigroup, Monoid) via (Generically Deps)
+
+newtype DepJSON = DepJSON (Map.Map ModuleName Deps)
+
+instance ToJson DepJSON where
+ json (DepJSON m) =
+ JSObject [
+ (moduleNameString target, JSObject [
+ ("sources", array sources normalise),
+ ("modules", array (fst modules) moduleNameString),
+ ("modules-boot", array (snd modules) moduleNameString),
+ ("packages",
+ JSArray [
+ package name unit_id package_id mods |
+ ((name, unit_id, package_id), mods) <- Map.toList packages
+ ]
+ ),
+ ("cpp", array cpp id),
+ ("options", array options id),
+ ("preprocessor", maybe JSNull JSString preprocessor)
+ ])
+ | (target, Deps {packages = PackageDeps packages, ..}) <- Map.toList m
+ ]
+ where
+ package name unit_id (PackageId package_id) mods =
+ JSObject [
+ ("id", JSString (unitIdString unit_id)),
+ ("name", JSString name),
+ ("package-id", JSString (unpackFS package_id)),
+ ("modules", array mods moduleNameString)
+ ]
+
+ array values render = JSArray (fmap (JSString . render) (Set.toList values))
+
+initDepJSON :: IO (IORef DepJSON)
+initDepJSON = newIORef $ DepJSON Map.empty
+
+insertDepJSON :: [ModuleName] -> Deps -> DepJSON -> DepJSON
+insertDepJSON targets dep (DepJSON m0) =
+ DepJSON
+ $ foldl'
+ ( \acc target ->
+ Map.insertWith
+ (Semigroup.<>)
+ target
+ dep
+ acc
+ )
+ m0
+ targets
+
+updateDepJSON :: Bool -> Maybe FilePath -> DepNode -> [Dep] -> DepJSON -> DepJSON
+updateDepJSON include_pkgs preprocessor DepNode {..} deps =
+ insertDepJSON [moduleName dn_mod] payload
+ where
+ payload = node_data Semigroup.<> foldMap dep deps
+
+ node_data =
+ mempty {
+ sources = Set.singleton dn_src,
+ preprocessor,
+ options = dn_options
+ }
+
+ dep = \case
+ DepHi {dep_mod, dep_local, dep_unit, dep_boot}
+ | dep_local
+ , let set = Set.singleton (moduleName dep_mod)
+ value | IsBoot <- dep_boot = (Set.empty, set)
+ | otherwise = (set, Set.empty)
+ -> mempty {modules = value}
+
+ | include_pkgs
+ , Just unit <- dep_unit
+ , let PackageName nameFS = unitPackageName unit
+ name = unpackFS nameFS
+ withLibName (PackageName c) = name ++ ":" ++ unpackFS c
+ lname = maybe name withLibName (unitComponentName unit)
+ key = (lname, unitId unit, unitPackageId unit)
+ -> mempty {packages = PackageDeps (Map.singleton key (Set.singleton (moduleName dep_mod)))}
+
+ | otherwise
+ -> mempty
+
+ DepCpp {dep_path} ->
+ mempty {cpp = Set.singleton dep_path}
=====================================
compiler/GHC/Driver/Pipeline/Execute.hs
=====================================
@@ -753,6 +753,7 @@ runHscPhase pipe_env hsc_env0 input_fn src_flavour = do
ms_iface_date = hi_date,
ms_hie_date = hie_date,
ms_textual_imps = imps,
+ ms_opts = [],
ms_srcimps = src_imps }
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -753,6 +753,9 @@ addDepExcludeMod m d
addDepSuffix :: FilePath -> DynFlags -> DynFlags
addDepSuffix s d = d { depSuffixes = s : depSuffixes d }
+setDepJSON :: FilePath -> DynFlags -> DynFlags
+setDepJSON f d = d { depJSON = Just f }
+
addCmdlineFramework f d = d { cmdlineFrameworks = f : cmdlineFrameworks d}
addGhcVersionFile :: FilePath -> DynFlags -> DynFlags
@@ -1218,6 +1221,7 @@ dynamic_flags_deps = [
, make_ord_flag defGhcFlag "include-pkg-deps"
(noArg (setDepIncludePkgDeps True))
, make_ord_flag defGhcFlag "exclude-module" (hasArg addDepExcludeMod)
+ , make_ord_flag defGhcFlag "dep-json" (hasArg setDepJSON)
-------- Linking ----------------------------------------------------
, make_ord_flag defGhcFlag "no-link"
=====================================
compiler/GHC/Unit/Info.hs
=====================================
@@ -117,6 +117,9 @@ instance Outputable PackageId where
instance Outputable PackageName where
ppr (PackageName str) = ftext str
+instance Ord PackageId where
+ PackageId p1 `compare` PackageId p2 = p1 `lexicalCompareFS` p2
+
unitPackageIdString :: GenUnitInfo u -> String
unitPackageIdString pkg = unpackFS str
where
=====================================
compiler/GHC/Unit/Module/ModSummary.hs
=====================================
@@ -83,6 +83,8 @@ data ModSummary
-- ^ Source imports of the module
ms_textual_imps :: [(PkgQual, Located ModuleName)],
-- ^ Non-source imports of the module from the module *text*
+ ms_opts :: ![String],
+ -- ^ OPTIONS and LANGUAGE pragmas of the source file
ms_parsed_mod :: Maybe HsParsedModule,
-- ^ The parsed, nonrenamed source, if we have it. This is also
-- used to support "inline module syntax" in Backpack files.
=====================================
compiler/GHC/Unit/State.hs
=====================================
@@ -71,6 +71,7 @@ module GHC.Unit.State (
unwireUnit)
where
+import Data.Foldable (find)
import GHC.Prelude
import GHC.Driver.DynFlags
@@ -903,8 +904,18 @@ applyPackageFlag prec_map pkg_map closure unusable no_hide_others pkgs vm flag =
ExposePackage _ arg (ModRenaming b rns) ->
case findPackages prec_map pkg_map closure arg pkgs unusable of
Left ps -> Failed (PackageFlagErr flag ps)
- Right (p:_) -> Succeeded vm'
+ Right ps@(p0:_) -> Succeeded vm'
where
+ p | PackageArg _ <- arg = fromMaybe p0 mainPackage
+ | otherwise = p0
+
+ mainPackage = find (\ u -> isNothing (unitComponentName u)) matchFirst
+
+ matchFirst = filter (\ u -> unitPackageName u == firstName && unitPackageVersion u == firstVersion) ps
+
+ firstName = unitPackageName p0
+ firstVersion = unitPackageVersion p0
+
n = fsPackageName p
-- If a user says @-unit-id p[A=<A>]@, this imposes
@@ -1030,6 +1041,13 @@ matchingStr :: String -> UnitInfo -> Bool
matchingStr str p
= str == unitPackageIdString p
|| str == unitPackageNameString p
+ || matchSublibrary
+ where
+ matchSublibrary
+ | Just (PackageName c) <- unitComponentName p
+ = str == (unitPackageNameString p ++ ":" ++ unpackFS c)
+ | otherwise
+ = False
matchingId :: UnitId -> UnitInfo -> Bool
matchingId uid p = uid == unitId p
=====================================
compiler/ghc.cabal.in
=====================================
@@ -528,6 +528,7 @@ Library
GHC.Driver.Make
GHC.Driver.MakeAction
GHC.Driver.MakeFile
+ GHC.Driver.MakeFile.JSON
GHC.Driver.Monad
GHC.Driver.Phases
GHC.Driver.Pipeline
=====================================
configure.ac
=====================================
@@ -13,7 +13,7 @@ dnl
# see what flags are available. (Better yet, read the documentation!)
#
-AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.13], [glasgow-haskell-bugs(a)haskell.org] [ghc-AC_PACKAGE_VERSION])
+AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.12.1], [glasgow-haskell-bugs(a)haskell.org] [ghc-AC_PACKAGE_VERSION])
# Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable
# to be useful (cf #19058). However, the version must have three components
# (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are
@@ -22,7 +22,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.13], [glasgow-hask
AC_CONFIG_MACRO_DIRS([m4])
# Set this to YES for a released version, otherwise NO
-: ${RELEASE=NO}
+: ${RELEASE=YES}
# The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line
# above. If this is not a released version, then we will append the
=====================================
docs/users_guide/separate_compilation.rst
=====================================
@@ -1520,6 +1520,22 @@ generation are:
is only a temporary file that GHC will always generate, it is not output as
a dependency.
+.. ghc-flag:: -dep-json ⟨file⟩
+ :shortdesc: Also emit ⟨file⟩ as a JSON file containing dependencies
+ :type: dynamic
+ :category: redirect-output
+
+ In addition to the makefile, also emit ⟨file⟩ as a JSON file
+ containing the same dependencies info, so it can be parsed by
+ external build systems. The JSON file contains a single object,
+ mapping each target to a list of dependencies.
+ In addition to the makefile, each module's payload will contain the
+ values of ``OPTIONS`` and ``LANGUAGE`` pragmas of the source
+ file, so it can be parsed by external build systems. Each ``LANGUAGE``
+ pragma is represented as an option as well, e.g.
+ ``{-# LANGUAGE TemplateHaskell #-}`` is represented as
+ ``"-XTemplateHaskell"``.
+
.. _orphan-modules:
Orphan modules and instance declarations
=====================================
docs/users_guide/using.rst
=====================================
@@ -366,7 +366,7 @@ The available mode flags are:
.. ghc-flag:: -M
:shortdesc: generate dependency information suitable for use in a
- ``Makefile``; see :ref:`makefile-dependencies` for details.
+ ``Makefile`` or as JSON; see :ref:`makefile-dependencies` for details.
:type: mode
:category: modes
=====================================
testsuite/tests/driver/T24384/A.hs
=====================================
@@ -0,0 +1,5 @@
+{-# language Strict #-}
+{-# options_ghc -fexpose-all-unfoldings #-}
+module A where
+
+import {-# source #-} C
=====================================
testsuite/tests/driver/T24384/B.hs
=====================================
@@ -0,0 +1,2 @@
+{-# options_ghc -F -pgmF ./preproc.sh #-}
+module B where
=====================================
testsuite/tests/driver/T24384/C.hs
=====================================
@@ -0,0 +1,6 @@
+module C where
+
+import A
+import Data.Set
+
+data C = C
=====================================
testsuite/tests/driver/T24384/C.hs-boot
=====================================
@@ -0,0 +1,5 @@
+module C where
+
+import E
+
+data C
=====================================
testsuite/tests/driver/T24384/D.hs
=====================================
@@ -0,0 +1,4 @@
+module D where
+
+import B
+import C
=====================================
testsuite/tests/driver/T24384/E.hs
=====================================
@@ -0,0 +1,14 @@
+module E where
+
+import Language.Haskell.TH.Syntax
+import Dep
+import DepPub
+
+e :: Q Exp
+e = lift (5 :: Integer)
+
+edep :: ()
+edep = dep
+
+edepPub :: ()
+edepPub = depPub
=====================================
testsuite/tests/driver/T24384/Makefile
=====================================
@@ -0,0 +1,10 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+T24384:
+ ./setup-dep.sh "$(TEST_HC)" "$(TEST_HC_OPTS)" "$(CABAL_MINIMAL_BUILD)" "$(GHC_PKG)"
+ mkdir -p lib
+ mv B.hs lib/
+ '$(TEST_HC)' A.hs lib/B.hs C.hs D.hs E.hs -M -dep-json dep.json -include-pkg-deps -include-cpp-deps -package-db ./db -hide-all-packages -package base -package containers -package template-haskell -package dep -package dep:pub
+ cat dep.json
=====================================
testsuite/tests/driver/T24384/T24384.stdout
=====================================
@@ -0,0 +1 @@
+{"A":{"sources":["A.hs"],"modules":[],"modules-boot":["C"],"packages":[{"id":"base","name":"base","package-id":"base-4.20.0.0","modules":["Prelude"]}],"cpp":[],"options":["-XStrict","-fexpose-all-unfoldings"],"preprocessor":null},"B":{"sources":["lib/B.hs"],"modules":["A"],"modules-boot":[],"packages":[{"id":"base","name":"base","package-id":"base-4.20.0.0","modules":["Prelude"]}],"cpp":[],"options":[],"preprocessor":"./preproc.sh"},"C":{"sources":["C.hs","C.hs-boot"],"modules":["A","E"],"modules-boot":[],"packages":[{"id":"base","name":"base","package-id":"base-4.20.0.0","modules":["Prelude"]},{"id":"containers-0.7-inplace","name":"containers","package-id":"containers-0.7","modules":["Data.Set"]}],"cpp":[],"options":[],"preprocessor":null},"D":{"sources":["D.hs"],"modules":["B","C"],"modules-boot":[],"packages":[{"id":"base","name":"base","package-id":"base-4.20.0.0","modules":["Prelude"]}],"cpp":[],"options":[],"preprocessor":null},"E":{"sources":["E.hs"],"modules":[],"modules-boot":[],"packages":[{"id":"base","name":"base","package-id":"base-4.20.0.0","modules":["Prelude"]},{"id":"dep-1-Acdff5K3xp09fO6uiTrnge","name":"dep","package-id":"dep-1","modules":["Dep"]},{"id":"dep-1-8mhA0yJkyEn42CuhdNx93G-pub","name":"dep:pub","package-id":"dep-1","modules":["DepPub"]},{"id":"template-haskell","name":"template-haskell","package-id":"template-haskell-2.22.0.0","modules":["Language.Haskell.TH.Syntax"]}],"cpp":[],"options":[],"preprocessor":null}}
\ No newline at end of file
=====================================
testsuite/tests/driver/T24384/all.T
=====================================
@@ -0,0 +1 @@
+test('T24384', [extra_files(['A.hs', 'B.hs', 'C.hs', 'C.hs-boot', 'D.hs', 'E.hs', 'preproc.sh', 'setup-dep.sh'])], makefile_test, [])
=====================================
testsuite/tests/driver/T24384/preproc.sh
=====================================
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+sed '/preproc/d' $2 > $3
+echo 'import A' >> $3
=====================================
testsuite/tests/driver/T24384/setup-dep.sh
=====================================
@@ -0,0 +1,65 @@
+#!/usr/bin/env bash
+
+set -eu
+
+ghc="$1"
+ghc_opts="$2"
+config_options="$3"
+ghc_pkg="$4"
+base=$(cd $(dirname $0); pwd)
+
+mkdir -p dep/{int,pub}
+$ghc_pkg init ./db
+
+cd dep/
+
+cat > dep.cabal <<EOF
+cabal-version: 3.4
+name: dep
+version: 1
+build-type: Simple
+library
+ default-language: Haskell2010
+ exposed-modules: Dep
+ build-depends: base, dep:int
+library int
+ default-language: Haskell2010
+ hs-source-dirs: int
+ exposed-modules: DepInt
+ build-depends: base
+library pub
+ default-language: Haskell2010
+ hs-source-dirs: pub
+ visibility: public
+ exposed-modules: DepPub
+ build-depends: base
+EOF
+
+cat > Dep.hs <<EOF
+module Dep where
+import DepInt
+dep :: ()
+dep = depInt
+EOF
+
+cat > int/DepInt.hs <<EOF
+module DepInt where
+depInt :: ()
+depInt = ()
+EOF
+
+cat > pub/DepPub.hs <<EOF
+module DepPub where
+depPub :: ()
+depPub = ()
+EOF
+
+cat > Setup.hs <<EOF
+import Distribution.Simple
+main = defaultMain
+EOF
+
+eval $ghc $ghc_opts -v0 --make Setup
+eval ./Setup configure $config_options --with-ghc="'$ghc'" --with-hc-pkg="'$ghc_pkg'" --ghc-options="'$ghc_opts'" --package-db="'$base/db'" -v0
+./Setup build -v0
+./Setup register --inplace -v0
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f9e476f5d0430ef8fe03f728d4fb29…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/f9e476f5d0430ef8fe03f728d4fb29…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/torsten.schmits/mercury-fixed] release
by Torsten Schmits (@torsten.schmits) 22 Oct '25
by Torsten Schmits (@torsten.schmits) 22 Oct '25
22 Oct '25
Torsten Schmits pushed to branch wip/torsten.schmits/mercury-fixed at Glasgow Haskell Compiler / GHC
Commits:
f9e476f5 by Torsten Schmits at 2025-10-22T15:06:23+02:00
release
- - - - -
1 changed file:
- configure.ac
Changes:
=====================================
configure.ac
=====================================
@@ -13,7 +13,7 @@ dnl
# see what flags are available. (Better yet, read the documentation!)
#
-AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.13], [glasgow-haskell-bugs(a)haskell.org] [ghc-AC_PACKAGE_VERSION])
+AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.12.1], [glasgow-haskell-bugs(a)haskell.org] [ghc-AC_PACKAGE_VERSION])
# Version on master must be X.Y (not X.Y.Z) for ProjectVersionMunged variable
# to be useful (cf #19058). However, the version must have three components
# (X.Y.Z) on stable branches (e.g. ghc-9.2) to ensure that pre-releases are
@@ -22,7 +22,7 @@ AC_INIT([The Glorious Glasgow Haskell Compilation System], [9.13], [glasgow-hask
AC_CONFIG_MACRO_DIRS([m4])
# Set this to YES for a released version, otherwise NO
-: ${RELEASE=NO}
+: ${RELEASE=YES}
# The primary version (e.g. 7.5, 7.4.1) is set in the AC_INIT line
# above. If this is not a released version, then we will append the
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f9e476f5d0430ef8fe03f728d4fb297…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/f9e476f5d0430ef8fe03f728d4fb297…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T23162-spj] 11 commits: Big increment in rewriter tracking
by Simon Peyton Jones (@simonpj) 22 Oct '25
by Simon Peyton Jones (@simonpj) 22 Oct '25
22 Oct '25
Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC
Commits:
2842aa8a by Simon Peyton Jones at 2025-10-22T09:20:06+01:00
Big increment in rewriter tracking
Needs more documentation
More tidying up of rewriter sets
- - - - -
087641b7 by Simon Peyton Jones at 2025-10-22T09:20:06+01:00
Do not treat CoercionHoles as free variables in coercions
This fixes a long-standing wart in the free-variable finder;
now CoercionHoles are no longer treated as a "free variable"
of a coercion.
I got big and unexpected performance regressions when making
this change. Turned out that CallArity didn't discover that
the free variable finder could be eta-expanded, which gave very
poor code.
So I re-used Note [The one-shot state monad trick] for Endo,
resulting in GHC.Utils.EndoOS. Very simple, big win.
- - - - -
5728c534 by Simon Peyton Jones at 2025-10-22T09:20:06+01:00
Fix buglet in solving equalities from QCIs
- - - - -
6fb8ad25 by Simon Peyton Jones at 2025-10-22T09:20:06+01:00
Improve equality checking for foralls a bit
...by re-using the TcEvBindsVar
- - - - -
fed02e8e by Simon Peyton Jones at 2025-10-22T09:20:06+01:00
Update debug-tracing in CallArity
No effect on behaviour, and commented out anyway
- - - - -
50ee09d4 by Simon Peyton Jones at 2025-10-22T09:20:06+01:00
Wibble Endo
- - - - -
ba99fc22 by Simon Peyton Jones at 2025-10-22T09:20:06+01:00
Wibble CoercionHole free vars
- - - - -
2d13e782 by Simon Peyton Jones at 2025-10-22T09:20:06+01:00
Wibble improve forall
- - - - -
ddcd5a28 by Simon Peyton Jones at 2025-10-22T09:20:07+01:00
Comments only -- remove dangling Note references
- - - - -
7da8daaf by Simon Peyton Jones at 2025-10-22T13:10:48+01:00
Accept error message wibbles
- - - - -
df22e143 by Simon Peyton Jones at 2025-10-22T13:11:02+01:00
More rewriter-set refactoring
* Introduce and use CoercionPlusHoles
* More documentation
- - - - -
36 changed files:
- compiler/GHC/Core/Opt/CallArity.hs
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Irred.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Rewrite.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Evidence.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Zonk/TcType.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/Types/Unique/DSM.hs
- + compiler/GHC/Utils/EndoOS.hs
- compiler/ghc.cabal.in
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/partial-sigs/should_fail/T14584a.stderr
- testsuite/tests/quantified-constraints/T15359.hs
- testsuite/tests/rep-poly/T13233.stderr
- testsuite/tests/rep-poly/T14561b.stderr
- testsuite/tests/rep-poly/T19709b.stderr
- testsuite/tests/rep-poly/T23903.stderr
- testsuite/tests/typecheck/should_compile/T25266a.stderr
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3030178d013f053d85c140f2e8b7b6…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/3030178d013f053d85c140f2e8b7b6…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/torsten.schmits/mercury-fixed
by Torsten Schmits (@torsten.schmits) 22 Oct '25
by Torsten Schmits (@torsten.schmits) 22 Oct '25
22 Oct '25
Torsten Schmits pushed new branch wip/torsten.schmits/mercury-fixed at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/torsten.schmits/mercury-fixed
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/bchinn-argparse-filetype] 19 commits: Add submodules for template-haskell-lift and template-haskell-quasiquoter
by Brandon Chinn (@brandonchinn178) 22 Oct '25
by Brandon Chinn (@brandonchinn178) 22 Oct '25
22 Oct '25
Brandon Chinn pushed to branch wip/bchinn-argparse-filetype at Glasgow Haskell Compiler / GHC
Commits:
4be32153 by Teo Camarasu at 2025-10-15T08:06:09-04:00
Add submodules for template-haskell-lift and template-haskell-quasiquoter
These two new boot libraries expose stable subsets of the
template-haskell interface.
This is an implemenation of the GHC proposal https://github.com/ghc-proposals/ghc-proposals/pull/696
Work towards #25262
- - - - -
0c00c9c3 by Ben Gamari at 2025-10-15T08:06:51-04:00
rts: Eliminate uses of implicit constant arrays
Folding of `const`-sized variable-length arrays to a constant-length
array is a gnu extension which clang complains about.
Closes #26502.
- - - - -
bf902a1d by Fendor at 2025-10-15T16:00:59-04:00
Refactor distinct constructor tables map construction
Adds `GHC.Types.Unique.FM.alterUFM_L`, `GHC.Types.Unique.DFM.alterUDFM_L`
`GHC.Data.Word64Map.alterLookup` to support fusion of distinct
constructor data insertion and lookup during the construction of the `DataCon`
map in `GHC.Stg.Debug.numberDataCon`.
Co-authored-by: Fendor <fendor(a)posteo.de>
Co-authored-by: Finley McIlwaine <finleymcilwaine(a)gmail.com>
- - - - -
b3585ba1 by Fendor at 2025-10-15T16:00:59-04:00
Allow per constructor refinement of distinct-constructor-tables
Introduce `-fno-distinct-constructor-tables`. A distinct constructor table
configuration is built from the combination of flags given, in order. For
example, to only generate distinct constructor tables for a few specific
constructors and no others, just pass
`-fdistinct-constructor-tables-only=C1,...,CN`.
This flag can be supplied multiple times to extend the set of
constructors to generate a distinct info table for.
You can disable generation of distinct constructor tables for all
configurations by passing `-fno-distinct-constructor-tables`.
The various configurations of these flags is included in the `DynFlags`
fingerprints, which should result in the expected recompilation logic.
Adds a test that checks for distinct tables for various given or omitted
constructors.
Updates CountDepsAst and CountDepsParser tests to account for new dependencies.
Fixes #23703
Co-authored-by: Fendor <fendor(a)posteo.de>
Co-authored-by: Finley McIlwaine <finleymcilwaine(a)gmail.com>
- - - - -
e17dc695 by fendor at 2025-10-15T16:01:41-04:00
Fix typos in haddock documentation for stack annotation API
- - - - -
f85058d3 by Zubin Duggal at 2025-10-17T13:50:52+05:30
compiler: Attempt to systematize Unique tags by introducing an ADT for each different tag
Fixes #26264
Metric Decrease:
T9233
- - - - -
c85c845d by sheaf at 2025-10-17T22:35:32-04:00
Don't prematurely final-zonk PatSyn declarations
This commit makes GHC hold off on the final zonk for pattern synonym
declarations, in 'GHC.Tc.TyCl.PatSyn.tc_patsyn_finish'.
This accommodates the fact that pattern synonym declarations without a
type signature can contain unfilled metavariables, e.g. if the RHS of
the pattern synonym involves view-patterns whose type mentions promoted
(level 0) metavariables. Just like we do for ordinary function bindings,
we should allow these metavariables to be settled later, instead of
eagerly performing a final zonk-to-type.
Now, the final zonking-to-type for pattern synonyms is performed in
GHC.Tc.Module.zonkTcGblEnv.
Fixes #26465
- - - - -
ba3e5bdd by Rodrigo Mesquita at 2025-10-18T16:57:18-04:00
Move code-gen aux symbols from ghc-internal to rts
These symbols were all previously defined in ghc-internal and made the
dependency structure awkward, where the rts may refer to some of these
symbols and had to work around that circular dependency the way
described in #26166.
Moreover, the code generator will produce code that uses these symbols!
Therefore, they should be available in the rts:
PRINCIPLE: If the code generator may produce code which uses this
symbol, then it should be defined in the rts rather than, say,
ghc-internal.
That said, the main motivation is towards fixing #26166.
Towards #26166. Pre-requisite of !14892
- - - - -
f31de2a9 by Ben Gamari at 2025-10-18T16:57:18-04:00
rts: Avoid static symbol references to ghc-internal
This resolves #26166, a bug due to new constraints placed by Apple's
linker on undefined references.
One source of such references in the RTS is the many symbols referenced
in ghc-internal. To mitigate #26166, we make these references dynamic,
as described in Note [RTS/ghc-internal interface].
Fixes #26166
Co-authored-by: Rodrigo Mesquita <rodrigo.m.mesquita(a)gmail.com>
Co-authored-by: Cheng Shao <terrorjack(a)type.dance>
- - - - -
43fdfddc by Ben Gamari at 2025-10-18T16:57:18-04:00
compiler: Rename isMathFun -> isLibcFun
This set includes more than just math functions.
- - - - -
4ed5138f by Ben Gamari at 2025-10-18T16:57:18-04:00
compiler: Add libc allocator functions to libc_funs
Prototypes for these are now visible from `Prim.h`, resulting in
multiple-declaration warnings in the unregisterised job.
- - - - -
9a0a076b by Ben Gamari at 2025-10-18T16:57:18-04:00
rts: Minimize header dependencies of Prim.h
Otherwise we will end up with redundant and incompatible declarations
resulting in warnings during the unregisterised build.
- - - - -
26b8a414 by Diego Antonio Rosario Palomino at 2025-10-18T16:58:10-04:00
Cmm Parser: Fix incorrect example in comment
The Parser.y file contains a comment with an incorrect example of textual
Cmm (used in .cmm files). This commit updates the comment to ensure it
reflects valid textual Cmm syntax.
Fixes #26313
- - - - -
d4a9d6d6 by ARATA Mizuki at 2025-10-19T18:43:47+09:00
Handle implications between x86 feature flags
This includes:
* Multiple -msse* options can be specified
* -mavx implies -msse4.2
* -mavx2 implies -mavx
* -mfma implies -mavx
* -mavx512f implies -mavx2 and -mfma
* -mavx512{cd,er,pf} imply -mavx512f
Closes #24989
Co-authored-by: sheaf <sam.derbyshire(a)gmail.com>
- - - - -
c9b8465c by Cheng Shao at 2025-10-20T10:16:00-04:00
wasm: workaround WebKit bug in dyld
This patch works around a WebKit bug and allows dyld to run on WebKit
based platforms as well. See added note for detailed explanation.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
91b6be10 by Julian Ospald at 2025-10-20T18:21:03-04:00
Improve error handling in 'getPackageArchives'
When the library dirs in the package conf files are not set up correctly,
the JS linker will happily ignore such packages and not link against them,
although they're part of the link plan.
Fixes #26383
- - - - -
6c5269da by Sven Tennie at 2025-10-20T18:21:44-04:00
Align coding style
Improve readability by using the same style for all constructor calls in
this function.
- - - - -
3d305889 by Sven Tennie at 2025-10-20T18:21:44-04:00
Reduce complexity by removing joins with mempty
ldArgs, cArgs and cppArgs are all `mempty`. Thus concatenating them adds
nothing but some complexity while reading the code.
- - - - -
472af3e0 by Brandon Chinn at 2025-10-21T21:08:57-07:00
Replace deprecated argparse.FileType
- - - - -
175 changed files:
- .gitmodules
- compiler/GHC/Builtin/Uniques.hs
- compiler/GHC/Cmm/CLabel.hs
- compiler/GHC/Cmm/Info.hs
- compiler/GHC/Cmm/Info/Build.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Cmm/Pipeline.hs
- compiler/GHC/Cmm/UniqueRenamer.hs
- compiler/GHC/CmmToAsm/Config.hs
- compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToAsm/X86/Instr.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/Base.hs
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Opt/Monad.hs
- compiler/GHC/Core/Opt/Pipeline.hs
- compiler/GHC/Core/Opt/Simplify/Monad.hs
- compiler/GHC/Core/PatSyn.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Data/Word64Map/Internal.hs
- compiler/GHC/Data/Word64Map/Lazy.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Config/CmmToAsm.hs
- compiler/GHC/Driver/Config/Stg/Debug.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/HsToCore/Foreign/C.hs
- compiler/GHC/HsToCore/Foreign/JavaScript.hs
- compiler/GHC/HsToCore/Foreign/Wasm.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Utils.hs
- compiler/GHC/Iface/Binary.hs
- compiler/GHC/Iface/Flags.hs
- compiler/GHC/Iface/Recomp/Flags.hs
- compiler/GHC/Iface/Rename.hs
- compiler/GHC/JS/JStg/Monad.hs
- compiler/GHC/Linker/Dynamic.hs
- compiler/GHC/Linker/Static.hs
- compiler/GHC/Platform.hs
- compiler/GHC/Platform/Reg.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Stg/Debug.hs
- + compiler/GHC/Stg/Debug/Types.hs
- compiler/GHC/Stg/EnforceEpt.hs
- compiler/GHC/Stg/Pipeline.hs
- compiler/GHC/StgToCmm/ExtCode.hs
- compiler/GHC/StgToCmm/Monad.hs
- compiler/GHC/StgToJS/CodeGen.hs
- compiler/GHC/StgToJS/Ids.hs
- compiler/GHC/StgToJS/Linker/Linker.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/Types/Name/Cache.hs
- compiler/GHC/Types/Unique.hs
- compiler/GHC/Types/Unique/DFM.hs
- compiler/GHC/Types/Unique/DSM.hs
- compiler/GHC/Types/Unique/FM.hs
- compiler/GHC/Types/Unique/Supply.hs
- compiler/Language/Haskell/Syntax/Binds.hs
- compiler/ghc.cabal.in
- docs/users_guide/9.16.1-notes.rst
- docs/users_guide/compare-flags.py
- docs/users_guide/debug-info.rst
- docs/users_guide/using.rst
- hadrian/src/Packages.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Rules/Libffi.hs
- hadrian/src/Settings/Builders/Cabal.hs
- hadrian/src/Settings/Builders/Common.hs
- hadrian/src/Settings/Builders/DeriveConstants.hs
- hadrian/src/Settings/Builders/Hsc2Hs.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- libraries/ghc-experimental/src/GHC/Stack/Annotation/Experimental.hs
- + libraries/ghc-internal/cbits/RtsIface.c
- libraries/ghc-internal/ghc-internal.cabal.in
- + libraries/ghc-internal/include/RtsIfaceSymbols.h
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Quote.hs
- + libraries/template-haskell-lift
- + libraries/template-haskell-quasiquoter
- rts/BuiltinClosures.c
- rts/CloneStack.h
- rts/Compact.cmm
- rts/ContinuationOps.cmm
- rts/Exception.cmm
- rts/Prelude.h
- rts/PrimOps.cmm
- rts/Printer.c
- rts/RtsAPI.c
- rts/RtsStartup.c
- rts/RtsSymbols.c
- + rts/RtsToHsIface.c
- rts/StgStdThunks.cmm
- rts/configure.ac
- − rts/external-symbols.list.in
- rts/gen_event_types.py
- rts/include/Rts.h
- rts/include/RtsAPI.h
- rts/include/Stg.h
- + rts/include/rts/RtsToHsIface.h
- rts/include/rts/Types.h
- rts/include/stg/Prim.h
- rts/posix/OSMem.c
- rts/posix/Signals.c
- libraries/ghc-internal/cbits/atomic.c → rts/prim/atomic.c
- libraries/ghc-internal/cbits/bitrev.c → rts/prim/bitrev.c
- libraries/ghc-internal/cbits/bswap.c → rts/prim/bswap.c
- libraries/ghc-internal/cbits/clz.c → rts/prim/clz.c
- libraries/ghc-internal/cbits/ctz.c → rts/prim/ctz.c
- libraries/ghc-internal/cbits/int64x2minmax.c → rts/prim/int64x2minmax.c
- libraries/ghc-internal/cbits/longlong.c → rts/prim/longlong.c
- libraries/ghc-internal/cbits/mulIntMayOflo.c → rts/prim/mulIntMayOflo.c
- libraries/ghc-internal/cbits/pdep.c → rts/prim/pdep.c
- libraries/ghc-internal/cbits/pext.c → rts/prim/pext.c
- libraries/ghc-internal/cbits/popcnt.c → rts/prim/popcnt.c
- libraries/ghc-internal/cbits/vectorQuotRem.c → rts/prim/vectorQuotRem.c
- libraries/ghc-internal/cbits/word2float.c → rts/prim/word2float.c
- − rts/rts.buildinfo.in
- rts/rts.cabal
- rts/wasm/JSFFI.c
- rts/wasm/scheduler.cmm
- rts/win32/libHSghc-internal.def
- testsuite/driver/runtests.py
- testsuite/tests/codeGen/should_gen_asm/all.T
- + testsuite/tests/codeGen/should_gen_asm/mavx-should-enable-popcnt.asm
- + testsuite/tests/codeGen/should_gen_asm/mavx-should-enable-popcnt.hs
- + testsuite/tests/codeGen/should_gen_asm/msse-option-order.asm
- + testsuite/tests/codeGen/should_gen_asm/msse-option-order.hs
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/ghc-api/T26264.hs
- + testsuite/tests/ghc-api/T26264.stdout
- testsuite/tests/ghc-api/all.T
- testsuite/tests/overloadedrecflds/should_compile/BootFldReexport.stderr
- testsuite/tests/overloadedrecflds/should_fail/T16745.stderr
- testsuite/tests/overloadedrecflds/should_fail/T18999_NoDisambiguateRecordFields.stderr
- + testsuite/tests/patsyn/should_compile/T26465b.hs
- + testsuite/tests/patsyn/should_compile/T26465c.hs
- + testsuite/tests/patsyn/should_compile/T26465d.hs
- + testsuite/tests/patsyn/should_compile/T26465d.stderr
- testsuite/tests/patsyn/should_compile/all.T
- + testsuite/tests/patsyn/should_fail/T26465.hs
- + testsuite/tests/patsyn/should_fail/T26465.stderr
- testsuite/tests/patsyn/should_fail/all.T
- testsuite/tests/perf/should_run/UniqLoop.hs
- testsuite/tests/regalloc/regalloc_unit_tests.hs
- + testsuite/tests/rts/ipe/distinct-tables/Main.hs
- + testsuite/tests/rts/ipe/distinct-tables/Makefile
- + testsuite/tests/rts/ipe/distinct-tables/X.hs
- + testsuite/tests/rts/ipe/distinct-tables/all.T
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables01.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables02.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables03.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables04.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables05.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables06.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables07.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables08.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables09.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables10.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables11.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables12.stdout
- + testsuite/tests/rts/ipe/distinct-tables/distinct_tables13.stdout
- testsuite/tests/simplCore/should_compile/rule2.stderr
- testsuite/tests/th/T8761.stderr
- utils/deriveConstants/Main.hs
- utils/jsffi/dyld.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cc7d226d6ed46c62cdc9daae4182c8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/cc7d226d6ed46c62cdc9daae4182c8…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T26503] Implement QualifiedStrings (#26503)
by Brandon Chinn (@brandonchinn178) 21 Oct '25
by Brandon Chinn (@brandonchinn178) 21 Oct '25
21 Oct '25
Brandon Chinn pushed to branch wip/T26503 at Glasgow Haskell Compiler / GHC
Commits:
fb50abde by Brandon Chinn at 2025-10-21T19:13:51-07:00
Implement QualifiedStrings (#26503)
- - - - -
41 changed files:
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/Errors/Types.hs
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Error/Codes.hs
- compiler/GHC/Types/StringMeta.hs
- docs/users_guide/9.16.1-notes.rst
- + docs/users_guide/exts/qualified_strings.rst
- libraries/ghc-boot-th/GHC/Boot/TH/Ppr.hs
- libraries/ghc-internal/src/GHC/Internal/LanguageExtensions.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- testsuite/tests/driver/T4437.hs
- testsuite/tests/ghc-api/annotations-literals/literals.stdout
- testsuite/tests/ghc-api/annotations-literals/parsed.stdout
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
- + testsuite/tests/qualified-strings/Makefile
- + testsuite/tests/qualified-strings/should_fail/Makefile
- + testsuite/tests/qualified-strings/should_fail/all.T
- + testsuite/tests/qualified-strings/should_fail/qstrings_multiline_no_ext.hs
- + testsuite/tests/qualified-strings/should_fail/qstrings_multiline_no_ext.stderr
- + testsuite/tests/qualified-strings/should_run/Example/ByteStringAscii.hs
- + testsuite/tests/qualified-strings/should_run/Example/ByteStringUtf8.hs
- + testsuite/tests/qualified-strings/should_run/Example/Text.hs
- + testsuite/tests/qualified-strings/should_run/Makefile
- + testsuite/tests/qualified-strings/should_run/all.T
- + testsuite/tests/qualified-strings/should_run/qstrings_expr.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_expr.stdout
- + testsuite/tests/qualified-strings/should_run/qstrings_pat.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_pat.stdout
- + testsuite/tests/qualified-strings/should_run/qstrings_th.hs
- + testsuite/tests/qualified-strings/should_run/qstrings_th.stdout
- utils/check-exact/ExactPrint.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fb50abde06132749c7d71e46e639437…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/fb50abde06132749c7d71e46e639437…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/bchinn-argparse-filetype] Replace deprecated argparse.FileType
by Brandon Chinn (@brandonchinn178) 21 Oct '25
by Brandon Chinn (@brandonchinn178) 21 Oct '25
21 Oct '25
Brandon Chinn pushed to branch wip/bchinn-argparse-filetype at Glasgow Haskell Compiler / GHC
Commits:
cc7d226d by Brandon Chinn at 2025-10-21T16:36:26-07:00
Replace deprecated argparse.FileType
- - - - -
3 changed files:
- docs/users_guide/compare-flags.py
- rts/gen_event_types.py
- testsuite/driver/runtests.py
Changes:
=====================================
docs/users_guide/compare-flags.py
=====================================
@@ -35,7 +35,7 @@ def expected_undocumented(flag: str) -> bool:
return False
-def read_documented_flags(doc_flags) -> Set[str]:
+def read_documented_flags(doc_flags: Path) -> Set[str]:
# Map characters that mark the end of a flag
# to whitespace.
trans = str.maketrans({
@@ -44,10 +44,10 @@ def read_documented_flags(doc_flags) -> Set[str]:
'⟨': ' ',
})
return {line.translate(trans).split()[0]
- for line in doc_flags.read().split('\n')
+ for line in doc_flags.read_text().split('\n')
if line != ''}
-def read_ghc_flags(ghc_path: str) -> Set[str]:
+def read_ghc_flags(ghc_path: Path) -> Set[str]:
ghc_output = subprocess.check_output([ghc_path, '--show-options'])
ghci_output = subprocess.check_output([ghc_path, '--interactive', '--show-options'])
@@ -63,16 +63,16 @@ def error(s: str):
def main() -> None:
import argparse
parser = argparse.ArgumentParser()
- parser.add_argument('--ghc', type=argparse.FileType('r'),
+ parser.add_argument('--ghc', type=Path,
help='path of GHC executable',
required=True)
- parser.add_argument('--doc-flags', type=argparse.FileType(mode='r', encoding='UTF-8'),
+ parser.add_argument('--doc-flags', type=Path,
help='path of ghc-flags.txt output from Sphinx',
required=True)
args = parser.parse_args()
doc_flags = read_documented_flags(args.doc_flags)
- ghc_flags = read_ghc_flags(args.ghc.name)
+ ghc_flags = read_ghc_flags(args.ghc)
failed = False
=====================================
rts/gen_event_types.py
=====================================
@@ -1,6 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
+from pathlib import Path
from typing import List, Union, Dict
from collections import namedtuple
@@ -198,17 +199,17 @@ def generate_event_types_defines() -> str:
def main() -> None:
import argparse
parser = argparse.ArgumentParser()
- parser.add_argument('--event-types-array', type=argparse.FileType('w'), metavar='FILE')
- parser.add_argument('--event-types-defines', type=argparse.FileType('w'), metavar='FILE')
+ parser.add_argument('--event-types-array', type=Path, metavar='FILE')
+ parser.add_argument('--event-types-defines', type=Path, metavar='FILE')
args = parser.parse_args()
check_events()
if args.event_types_array:
- args.event_types_array.write(generate_event_types_array())
+ args.event_types_array.write_text(generate_event_types_array())
if args.event_types_defines:
- args.event_types_defines.write(generate_event_types_defines())
+ args.event_types_defines.write_text(generate_event_types_defines())
if __name__ == '__main__':
main()
=====================================
testsuite/driver/runtests.py
=====================================
@@ -83,7 +83,7 @@ parser.add_argument("--way", action="append", help="just this way")
parser.add_argument("--skipway", action="append", help="skip this way")
parser.add_argument("--threads", type=int, help="threads to run simultaneously")
parser.add_argument("--verbose", type=int, choices=[0,1,2,3,4,5], help="verbose (Values 0 through 5 accepted)")
-parser.add_argument("--junit", type=argparse.FileType('wb'), help="output testsuite summary in JUnit format")
+parser.add_argument("--junit", type=Path, help="output testsuite summary in JUnit format")
parser.add_argument("--broken-test", action="append", default=[], help="a test name to mark as broken for this run")
parser.add_argument("--test-env", default='local', help="Override default chosen test-env.")
parser.add_argument("--perf-baseline", type=GitRef, metavar='COMMIT', help="Baseline commit for performance comparsons.")
@@ -91,7 +91,7 @@ perf_group.add_argument("--skip-perf-tests", action="store_true", help="skip per
perf_group.add_argument("--only-perf-tests", action="store_true", help="Only do performance tests")
parser.add_argument("--ignore-perf-failures", choices=['increases','decreases','all'],
help="Do not fail due to out-of-tolerance perf tests")
-parser.add_argument("--only-report-hadrian-deps", type=argparse.FileType('w'),
+parser.add_argument("--only-report-hadrian-deps", type=Path,
help="Dry run the testsuite and report all extra hadrian dependencies needed on the given file")
args = parser.parse_args()
@@ -615,14 +615,14 @@ else:
summary(t, f)
if args.junit:
- junit(t).write(args.junit)
- args.junit.close()
+ with args.junit.open("wb") as f:
+ junit(t).write(f)
if config.only_report_hadrian_deps:
print("WARNING - skipping all tests and only reporting required hadrian dependencies:", config.hadrian_deps)
- for d in config.hadrian_deps:
- print(d,file=config.only_report_hadrian_deps)
- config.only_report_hadrian_deps.close()
+ with config.only_report_hadrian_deps.open("w") as f:
+ for d in config.hadrian_deps:
+ print(d, file=f)
if len(t.unexpected_failures) > 0 or \
len(t.unexpected_stat_failures) > 0 or \
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc7d226d6ed46c62cdc9daae4182c8a…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/cc7d226d6ed46c62cdc9daae4182c8a…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc] Pushed new branch wip/bchinn-argparse-filetype
by Brandon Chinn (@brandonchinn178) 21 Oct '25
by Brandon Chinn (@brandonchinn178) 21 Oct '25
21 Oct '25
Brandon Chinn pushed new branch wip/bchinn-argparse-filetype at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/bchinn-argparse-filetype
You're receiving this email because of your account on gitlab.haskell.org.
1
0