Skip to content

Commit

Permalink
Forwarding GHC runtime system arguments.
Browse files Browse the repository at this point in the history
Normally GHC runtime system arguments are
processed before the program, and invisible to
System.Environment.getArgs.

We use GHC.Environment.getFullArgs to forward them,
and add an option rtsOptsHandling to describe
whether they should be appended by any other, or replaced
during relaunch.
  • Loading branch information
Michal J. Gajda committed Jul 16, 2012
1 parent 6ee75c7 commit 109dcb9
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
41 changes: 36 additions & 5 deletions Config/Dyre.hs
Expand Up @@ -99,11 +99,13 @@ import System.IO ( hPutStrLn, stderr )
import System.Directory ( doesFileExist, removeFile, canonicalizePath import System.Directory ( doesFileExist, removeFile, canonicalizePath
, getDirectoryContents, doesDirectoryExist ) , getDirectoryContents, doesDirectoryExist )
import System.FilePath ( (</>) ) import System.FilePath ( (</>) )
import System.Environment ( getArgs ) import System.Environment (getArgs)
import GHC.Environment (getFullArgs)
import Control.Exception (assert)


import Control.Monad ( when, filterM ) import Control.Monad ( when, filterM )


import Config.Dyre.Params ( Params(..) ) import Config.Dyre.Params ( Params(..), RTSOptionHandling(..) )
import Config.Dyre.Compile ( customCompile, getErrorPath, getErrorString ) import Config.Dyre.Compile ( customCompile, getErrorPath, getErrorString )
import Config.Dyre.Compat ( customExec ) import Config.Dyre.Compat ( customExec )
import Config.Dyre.Options ( getForceReconf, getDenyReconf, getDebug import Config.Dyre.Options ( getForceReconf, getDenyReconf, getDebug
Expand All @@ -124,6 +126,7 @@ defaultParams = Params
, ghcOpts = [] , ghcOpts = []
, forceRecomp = True , forceRecomp = True
, statusOut = hPutStrLn stderr , statusOut = hPutStrLn stderr
, rtsOptsHandling = RTSAppend []
} }


-- | 'wrapMain' is how Dyre recieves control of the program. It is expected -- | 'wrapMain' is how Dyre recieves control of the program. It is expected
Expand Down Expand Up @@ -183,10 +186,11 @@ wrapMain params@Params{projectName = pName} cfg = withDyreOptions params $
else enterMain errorData else enterMain errorData
where launchSub errorData tempBinary = do where launchSub errorData tempBinary = do
statusOut params $ "Launching custom binary " ++ tempBinary ++ "\n" statusOut params $ "Launching custom binary " ++ tempBinary ++ "\n"
givenArgs <- handleRTSOptions $ rtsOptsHandling params
-- Deny reconfiguration if a compile already failed. -- Deny reconfiguration if a compile already failed.
arguments <- case errorData of let arguments = case errorData of
Nothing -> getArgs Nothing -> givenArgs
Just _ -> ("--deny-reconf":) `fmap` getArgs Just _ -> "--deny-reconf":givenArgs
-- Execute -- Execute
customExec tempBinary $ Just arguments customExec tempBinary $ Just arguments
enterMain errorData = do enterMain errorData = do
Expand All @@ -209,3 +213,30 @@ recFiles d = do
subfiles <- concat `fmap` mapM recFiles dirs subfiles <- concat `fmap` mapM recFiles dirs
return $ files ++ subfiles return $ files ++ subfiles
else return [] else return []

assertM b = assert b $ return ()

-- | Filters GHC runtime system arguments:
filterRTSArgs = filt False
where
filt _ [] = []
filt _ ("--RTS":rest) = []
filt False ("+RTS" :rest) = filt True rest
filt True ("-RTS" :rest) = filt False rest
filt False (_ :rest) = filt False rest
filt True (arg :rest) = arg:filt True rest
--filt state args = error $ "Error filtering RTS arguments in state " ++ show state ++ " remaining arguments: " ++ show args

editRTSOptions opts (RTSReplace ls) = ls
editRTSOptions opts (RTSAppend ls) = opts ++ ls

handleRTSOptions h = do fargs <- getFullArgs
args <- getArgs
let rtsArgs = editRTSOptions (filterRTSArgs fargs) h
assertM $ not $ "--RTS" `elem` rtsArgs
case rtsArgs of
[] -> if not $ "+RTS" `elem` args
then return args -- cleaner output
else return $ "--RTS":args
_ -> return $ ["+RTS"] ++ rtsArgs ++ ["--RTS"] ++ args

9 changes: 8 additions & 1 deletion Config/Dyre/Params.hs
Expand Up @@ -3,7 +3,7 @@ Defines the 'Params' datatype which Dyre uses to define all
program-specific configuration data. Shouldn't be imported program-specific configuration data. Shouldn't be imported
directly, as 'Config.Dyre' re-exports it. directly, as 'Config.Dyre' re-exports it.
-} -}
module Config.Dyre.Params ( Params(..) ) where module Config.Dyre.Params ( Params(..), RTSOptionHandling(..) ) where


-- | This structure is how all kinds of useful data is fed into Dyre. Of -- | This structure is how all kinds of useful data is fed into Dyre. Of
-- course, only the 'projectName', 'realMain', and 'showError' fields -- course, only the 'projectName', 'realMain', and 'showError' fields
Expand Down Expand Up @@ -43,4 +43,11 @@ data Params cfgType = Params
-- when Dyre recompiles or launches anything. A good value -- when Dyre recompiles or launches anything. A good value
-- is 'hPutStrLn stderr', assuming there is no pressing -- is 'hPutStrLn stderr', assuming there is no pressing
-- reason to not put messages on stderr. -- reason to not put messages on stderr.
, rtsOptsHandling :: RTSOptionHandling
-- ^ Whether to append, or replace GHC runtime system options
-- with others.
} }

data RTSOptionHandling = RTSReplace [String] -- replaces RTS options with given list
| RTSAppend [String] -- merges given list with RTS options from command line (so that nothing is lost)

0 comments on commit 109dcb9

Please sign in to comment.