title: Using GHC API to compile Haskell sources to CORE and CORE to binary
body: <p><strong>The Idea</strong></p>
  
  <p>Hello! I want to create a program, that will generate Haskell Core and will use GHC API to compile it further into an executable. But before I will do it I want to construct a very basic example, showing how can we just compile Haskell sources into CORE and then into the binary file.</p>
  
  <p><strong>The problem</strong></p>
  
  <p>I have read a lot of documentation and tried many methods from GHC Api, but for now without success. I started with <a href="https://www.haskell.org/haskellwiki/GHC/As_a_library" rel="nofollow noreferrer">Official GHC Api introduction</a> and successfully compiled the examples. The examples show the usage of the following functions: <code>parseModule</code>, <code>typecheckModule</code>, <code>desugarModule</code>, <code>getNamesInScope</code> and <code>getModuleGraph</code> but does not cover the final compilation step. On the other hand, there are some functions in the api, whose names look related to the problem, like <a href="https://www.haskell.org/platform/doc/2013.2.0.0/ghc-api/HscMain.html" rel="nofollow noreferrer">HscMain.{hscCompileOneShot, hscCompileBatch}</a> or <a href="https://downloads.haskell.org/~ghc/latest/docs/html/libraries/ghc-7.8.4/GHC.html#g:6" rel="nofollow noreferrer">GHC.{compileToCoreModule, compileCoreToObj}</a>. I tried to use them, but I get runtime errors, like in this example:</p>
  
  <pre><code>import GHC
  import GHC.Paths ( libdir )
  import DynFlags
  targetFile = "Test.hs"
  
  main :: IO ()
  main = do
     res &lt;- example
     return ()
  
  example = 
      defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
        runGhc (Just libdir) $ do
          dflags &lt;- getSessionDynFlags
          let dflags' = foldl xopt_set dflags
                              [Opt_Cpp, Opt_ImplicitPrelude, Opt_MagicHash]
          setSessionDynFlags dflags'
          coreMod &lt;- compileToCoreModule targetFile
          compileCoreToObj False coreMod "foo" "bar"
          return () 
  </code></pre>
  
  <p>which can be compiled with <code>ghc -package ghc Main.hs</code> and which results in the following error during runtime:</p>
  
  <pre><code>Main: panic! (the 'impossible' happened)
    (GHC version 7.8.3 for x86_64-unknown-linux):
      expectJust mkStubPaths
  </code></pre>
  
  <p>which of course can be the result of wrong API usage, in particular, because of line <code>compileCoreToObj False coreMod "foo" "bar"</code>, wher the string are just random ones, because the documentation does not say much about them. If we look into the sources, it seems, that the first one is the output name and the second one is "extCore_filename", whatever it could be.</p>
  
  <p>Another worrying thing is the comment in the documentation next to the <code>compileCoreToObj</code> function: </p>
  
  <blockquote>
    <p>[...] This has only so far been tested with a single self-contained module.</p>
  </blockquote>
  
  <p>But I hope it will not introduce any further problems.</p>
  
  <p><strong>The question</strong></p>
  
  <p>What is the best possible way to create this solution? How can we create a minimal working example, that will load haskell sources, compile them into the CORE and then compile the core to final executable (using the GHC API). The intermediate step is needed for further replacement by custom CORE.</p>
  
  <p>As a side-question - is it currently possible to provide GHC with external core files or this feature is not implemented yet and I will have to construct the Core manually, using GHC.Api (related to: <a href="https://stackoverflow.com/questions/8927010/compiling-to-ghc-core?rq=1">Compiling to GHC Core</a>)</p>
  
  <p><strong>Update</strong></p>
  
  <p>I was finally able to create a small example allowing loading a module and compiling it to <code>.hi</code> and <code>.o</code> files. This is not a solution for the problem, because it does not allow me to replace the CORE and it does not link the object files into executables yet:</p>
  
  <pre><code>import GHC
  import GHC.Paths ( libdir )
  import DynFlags
  import Linker
  import Module
  targetFile = "Test.hs"
  
  main :: IO ()
  main = do
     res &lt;- example
     return ()
  
  example = 
      defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
        runGhc (Just libdir) $ do
          dflags &lt;- getSessionDynFlags
          let dflags2 = dflags { ghcLink   = LinkBinary
                               , hscTarget = HscAsm
                               }
          let dflags' = foldl xopt_set dflags2
                              [Opt_Cpp, Opt_ImplicitPrelude, Opt_MagicHash]
          setSessionDynFlags dflags'
          setTargets =&lt;&lt; sequence [guessTarget "Test.hs" Nothing]
  
          load LoadAllTargets
          return ()
  </code></pre>