动态加载编译的Haskell模块

我正在尝试使用GHC API动态编译和加载Haskell模块。 我了解API在不同版本之间波动很大,所以我特别谈论GHC 7.6。*。

我曾尝试在MacOS和Linux上运行相同的代码。 在这两种情况下,插件模块都能很好地编译,但在加载时出现以下错误: Cannot add module Plugin to context: not interpreted

这个问题类似于这个模块只有在主机程序的同一个运行过程中编译才加载的问题。

-- Host.hs: compile with ghc-7.6.*
-- $ ghc -package ghc -package ghc-paths Host.hs
-- Needs Plugin.hs in the same directory.
module Main where

import GHC
import GHC.Paths ( libdir )
import DynFlags
import Unsafe.Coerce

main :: IO ()
main =
    defaultErrorHandler defaultFatalMessager defaultFlushOut $ do
      result <- runGhc (Just libdir) $ do
        dflags <- getSessionDynFlags
        setSessionDynFlags dflags
        target <- guessTarget "Plugin.hs" Nothing
        setTargets [target]
        r <- load LoadAllTargets
        case r of
          Failed    -> error "Compilation failed"
          Succeeded -> do
            setContext [IIModule (mkModuleName "Plugin")]
            result <- compileExpr ("Plugin.getInt")
            let result' = unsafeCoerce result :: Int
            return result'
      print result

和插件:

-- Plugin.hs
module Plugin where

getInt :: Int
getInt = 33

问题是你正在使用IIModule 。 这表示您想要将模块及其中的所有内容,包括未导出的内容放入上下文中。 它与GHCi中带有星号的:load基本相同。 正如你已经注意到的,这只适用于解释代码,因为它让你“看看”模块。

但这不是你在这里需要的。 你想要的是加载它,就像你使用:module或一个import声明,它与编译模块一起工作。 为此,您使用IIDecl这需要进口报关单,你可以做simpleImportDecl

setContext [IIDecl $ simpleImportDecl (mkModuleName "Plugin")]
链接地址: http://www.djcxy.com/p/33321.html

上一篇: Dynamically loading compiled Haskell module

下一篇: Reduce size of executable produced by GHC