Haskell GHC Dynamic Compliation Only works on first compile
Asked Answered
O

1

7

Following the GHC tutorial posted here and alterations to this code following the advice in a previous stack overflow question I asked, I have created a program which is able to compile and run a module in Test.hs with a function print to print a string to the screen:

import GHC
import GHC.Paths
import DynFlags
import Unsafe.Coerce

main :: IO ()
main =
    defaultErrorHandler defaultLogAction $ do
      func <- runGhc (Just libdir) $ do
        dflags <- getSessionDynFlags
        setSessionDynFlags dflags
        target <- guessTarget "Test.hs" Nothing
        addTarget target
        r <- load LoadAllTargets
        case r of
          Failed -> error "Compilation failed"
          Succeeded -> do
            m <- findModule (mkModuleName "Test") Nothing
            setContext [IIModule m]
            value <- compileExpr ("Test.print")
            do let value' = (unsafeCoerce value) :: String -> IO ()
               return value'
      func "Hello"
      return ()

The problem with this code, as noted in the comments, is that it only seems to work the first time you run it (When Test.hs has not yet been complied). If you attempt to run the code a second time, the following error appears:

mkTopLevEnv: not interpreted main:Test

I believe this has something to do with the fact that the code has already been compiled. If I delete the .hi and .o files and run the program again, the program runs correctly with the correct output. What am I missing? I am currently using ghc version 7.4.1

(Note: I have tried looking through the GHC API but could not find any references to mkTopLevEnv)

Our answered 8/10, 2012 at 22:26 Comment(5)
As a workaround, you could get your program to delete the .hi and .o files itself if they exist!Possessory
I was considering this, but I would still be left with a big gap in the understanding of how the ghc api actually worksOur
Absolutely - it's an ugly workaround.Possessory
Does this happen when you run it twice in fast succession? Does it happen when you wait at least two seconds, so the timestamps are definitely different? here Simon Marlow suggests replacing guessTarget "Test.hs" Nothing with guessTarget "*Test.hs" Nothing, on the grounds that it tells GHC not to load the .o file. whole thread on a page via nabblePossessory
Don't get your hopes up, though, because the bug is marked as fixed, so it might not be your problem. However, if "*Test.hs" avoids loading the .o files, and the existence of the .o files is the problem, this workaround might yet work.Possessory
P
2

Simon Marlow suggests here that replacing

guessTarget "Test.hs" Nothing

with

guessTarget "*Test.hs" Nothing

should avoid the error you're getting, on the grounds that it tells GHC not to load the .o file.

See the whole thread on a page via nabble

Of course, you could delete the .hi and .o files each time, but that's an ugly workaround.

Possessory answered 16/10, 2012 at 1:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.