2012-09-03 10 views
7

Sto provando a creare un programma che digita i file haskell per me utilizzando l'API GHC. Ho ottenuto il controllo del tipo di lavoro per i file locali, ma ho un pacchetto cabale specifico che devo essere disponibile (lo stesso pacchetto di cui questo eseguibile farà parte). Come si aggiunge questa dipendenza di importazione?Trovare pacchetti di cabal quando si utilizza l'API GHC

Ho anche provato a compilare con ghc riga di comando per capirlo, usando ghc -package PKG-VER --make Test.hs -v ma sembra solo cercare nella directory locale per le importazioni.

mio codice attuale è simile al seguente:

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

Il pacchetto http://hackage.haskell.org/package/buildwrapper fa esattamente questo. Puoi usarlo come riferimento. – arrowd

risposta

5

sono riuscito a rendere il codice di lettura e TYPECHECK se stesso come segue:

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 

ecco come viene eseguito in 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> 

Quindi il trucco sembra essere quello di passare i pacchetti esposti nell'argomento dynflags a setSessionDynFlags. Vedere il modulo DynFlags per alcuni documenti.

+0

risulta che ho avuto anche degli errori stupidi (non presenti in questo esempio), ma questo era quello che chiedevo, quindi grazie! –

+0

Proprio come aggiornamento per la nuova GHC API (7.10.2): l'argomento per esporre un pacchetto "pkg" dovrebbe essere: 'ExposePackage (PackageArg" pkg ") $ ModRenaming True []' dove True (non documentato bene) in realtà espone il pacchetto. – Dmitry