The GHC API requires that some initialisation occurs before invocation. Specifically, parseStaticFlags
can only be called once.
I have functions that can call runGhc :: MaybeFilePath :: Ghc a -> IO a
multiple times to run some GHC API methods. However, some of that initialisation should only occur the first time that function is called.
I seem to remember from Yi
source that it is possible to create a global variable something like
ghcInitialised :: MVar (Bool,[String])
ghcInitialised = unsafePerformIO $ newMVar (False,[])
so that in the monadic action that calls runGhc
we can have
(init,flags) <- readMVar ghcInitialised
when (not init) $ do
...
(_,_,staticFlagWarnings) <- parseStaticFlags ...
...
putMVar ghcInitialised (True,staticFlagWarnings)
However, I can not recall exactly how it is done. This code is in the runMonad
function for the monad that wraps a GhcMonad
. I am well aware that using unsafePerformIO
is not pure or functional, but (at the time) this was the best way of achieving a practical result.
[Edit: the working solution:
{-# NOINLINE ghcInitialised #-}
ghcInitialised :: MVar (Bool,[String])
ghcInitialised = unsafePerformIO $ newMVar (False,[])
so that in the monadic action that calls runGhc
we can have
(init,flags) <- takeMVar ghcInitialised
when (not init) $ do
...
(_,_,staticFlagWarnings) <- parseStaticFlags ...
...
putMVar ghcInitialised (True,staticFlagWarnings)
IORef
notMVar
. – Walcott