2012-09-03 22 views
7

Estoy tratando de hacer un programa que tipee archivos haskell para mí usando la API GHC. Obtuve el tipo de comprobación para trabajar con los archivos locales, pero tengo un paquete cabal específico que necesito tener disponible también (el mismo paquete del que formará parte este ejecutable). ¿Cómo se agrega esta dependencia de importación?Encontrando paquetes cabal al usar la API GHC

También intenté compilar con la línea de comandos de ghc para resolver esto, usando ghc -package PKG-VER --make Test.hs -v pero parece que solo busca en el directorio local las importaciones.

Mi código actual es el siguiente:

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

El paquete http://hackage.haskell.org/package/buildwrapper hace exactamente esto. Puedes usarlo como referencia. – arrowd

Respuesta

5

logré hacer que el código leído y typecheck en sí de la siguiente manera:

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 

aquí es la forma en que se ejecuta en 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> 

Así que el truco parece ser pasar los paquetes expuestos en el argumento dynflags al setSessionDynFlags. Vea el módulo DynFlags para cierta documentación.

+0

resulta que también tuve algunos errores estúpidos (no están presentes en este ejemplo), pero esto fue lo que pedí, ¡así que gracias! –

+0

Al igual que la actualización para la última API de GHC (7.10.2): el argumento para exponer un paquete "pkg" debe ser: 'ExposePackage (PackageArg" pkg ") $ ModRenaming True []' donde es True (realmente no está bien documentado) expone el paquete. – Dmitry

Cuestiones relacionadas