2012-09-03 2 views
7

J'essaie de créer un programme qui typecarque les fichiers haskell pour moi en utilisant l'API GHC. J'ai vérifié que le type fonctionne bien pour les fichiers locaux, mais j'ai un paquet cabal spécifique dont j'ai besoin (le même paquet que cet exécutable sera inclus). Comment ajouter cette dépendance d'importation?Recherche de paquets cabal lors de l'utilisation de l'API GHC

J'ai également essayé de compiler avec la ligne de commande ghc pour comprendre cela, en utilisant ghc -package PKG-VER --make Test.hs -v mais il semble seulement chercher dans le répertoire local pour les importations.

Mon code actuel ressemble à ceci:

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

Le paquet http://hackage.haskell.org/package/buildwrapper fait exactement cela. Vous pouvez l'utiliser comme référence. – arrowd

Répondre

5

J'ai réussi à rendre votre code lu et se typecheck comme suit:

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 

voici comment il fonctionne 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> 

Donc l'astuce semble être de passer les paquets exposés dans l'argument dynflags à setSessionDynFlags. Voir le module DynFlags pour une documentation.

+0

s'avère que j'ai eu quelques erreurs stupides aussi (pas présent dans cet exemple), mais c'était ce que j'ai demandé, alors merci! –

+0

Juste comme mise à jour pour la nouvelle API GHC (7.10.2): l'argument pour exposer un paquet "pkg" devrait être: 'ExposePackage (PackageArg" pkg ") $ ModRenaming True []' où True (pas vraiment bien documenté) expose le paquet. – Dmitry

Questions connexes