2012-09-03 54 views
7

当我试图做出typechecks Haskell的文件我使用GHC API的程序寻找阴谋包。我已经获得了类型检查,可以用于本地文件,但是我有一个特定的cabal软件包,我需要它也可以使用(这个可执行文件将是该软件包的一部分)。如何添加此导入依赖项?使用GHC API

我也试图与GHC命令行编译摸不着头脑,用ghc -package PKG-VER --make Test.hs -v但似乎只在本地目录进口的样子。

我当前的代码如下所示:

import   Control.Exception 
import   Control.Monad 
import   Control.Monad.State 
import   DynFlags 
import   Exception 
import   GHC 
import   GHC.Paths   (libdir) 
typecheck :: MonadIO m => [FilePath] -> FilePath -> m() 
typecheck otherincludes fp = 
    liftIO . defaultErrorHandler defaultLogAction . runGhc (Just libdir) $ do 
    dynflags <- getSessionDynFlags 
    void $ setSessionDynFlags dynflags { includePaths = otherIncludes ++ includePaths dynflags } 
    target <- guessTarget fp Nothing 
    setTargets [target] 
    void $ load LoadAllTargets 
    deps <- depanal [] False 
    forM_ deps $ \ms -> parseModule ms >>= typecheckModule 
+2

的http://hackage.haskell.org/package/buildwrapper包正是这样做的。您可以将其用作参考。 – arrowd

回答

5

我设法让你的代码读取和类型检查本身如下:

package Test where 
import   Control.Exception 
import   Control.Monad 
import   Control.Monad.State 
import   DynFlags 
import   Exception 
import   GHC 
import   GHC.Paths   (libdir) 
typecheck :: MonadIO m => [FilePath] -> FilePath -> m() 
typecheck otherincludes fp = 
    liftIO . defaultErrorHandler defaultLogAction . runGhc (Just libdir) $ do 
    dynflags <- getSessionDynFlags 
    void $ setSessionDynFlags dynflags { 
     includePaths = otherincludes ++ includePaths dynflags, 
     packageFlags = [ExposePackage "ghc"]} } 
    target <- guessTarget fp Nothing 
    setTargets [target] 
    void $ load LoadAllTargets 
    deps <- depanal [] False 
    forM_ deps $ \ms -> parseModule ms >>= typecheckModule 

这里是如何在ghci中运行:

$ ghci Test.hs -package ghc 
GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help 
Loading package ghc-prim ... linking ... done. 
Loading package integer-gmp ... linking ... done. 
Loading package base ... linking ... done. 
Loading package array-0.4.0.0 ... linking ... done. 
Loading package deepseq-1.3.0.0 ... linking ... done. 
Loading package containers-0.4.2.1 ... linking ... done. 
Loading package filepath-1.3.0.0 ... linking ... done. 
Loading package old-locale-1.0.0.4 ... linking ... done. 
Loading package old-time-1.1.0.0 ... linking ... done. 
Loading package bytestring-0.9.2.1 ... linking ... done. 
Loading package unix-2.5.1.0 ... linking ... done. 
Loading package directory-1.1.0.2 ... linking ... done. 
Loading package pretty-1.1.1.0 ... linking ... done. 
Loading package process-1.1.0.1 ... linking ... done. 
Loading package Cabal-1.14.0 ... linking ... done. 
Loading package binary-0.5.1.0 ... linking ... done. 
Loading package bin-package-db-0.0.0.0 ... linking ... done. 
Loading package hoopl-3.8.7.3 ... linking ... done. 
Loading package hpc-0.5.1.1 ... linking ... done. 
Loading package template-haskell ... linking ... done. 
Loading package ghc-7.4.1 ... linking ... done. 
Ok, modules loaded: Test. 
Prelude Test> typecheck [] "Test.hs" 
Loading package transformers-0.3.0.0 ... linking ... done. 
Loading package mtl-2.1.1 ... linking ... done. 
Prelude Test> 

因此,关键似乎是在dynflags参数传递暴露包setSessionDynFlags。有关文档,请参阅DynFlags模块。

+0

事实证明我也有一些愚蠢的错误(在这个例子中不存在),但这是我要求的,所以谢谢! –

+0

正如更新较新的GHC API(7.10.2):参数揭露一包 “PKG” 应该是:'ExposePackage(PackageArg “PKG”)$ ModRenaming真[]'其中true(不是真的很好文档)实际上暴露包裹。 – Dmitry