Ich muss einige Informationen aus Kompilierungsskripten in Template Haskell übermitteln. Derzeit behalten die Kompilierungsskripte die Informationen in der Systemumgebung bei, daher lese ich sie nur mit System.Environment.getEnvironment
Wraps in runIO
. Gibt es einen besseren Weg, wie das Übergeben einiger Argumente ghc
(ähnlich wie -D...
beim C-Vorprozessor) oder vielleicht etwas, das speziell für diesen Zweck in TH entwickelt wurde?
70
addDependentFile
, um diese Datei bekannt zu machen,ghc --make
ist eine offensichtliche Alternative. Was sind die Probleme, die Sie mit dem aktuellen Schema haben?addDependentFile
wird für meinen Fall hilfreich sein. Das aktuelle Schema funktioniert, ich wollte nur wissen, ob es eine andere kanonische Methode gibt.location
Funktion auch verwenden , um das Stammverzeichnis des Projektverzeichnisses abzurufen (vorausgesetzt, Sie kennen den relativen Pfad vom aktuellen Modul zum Stammverzeichnis). Hier ist ein Beispiel .Antworten:
Da sich so viele Menschen für die Frage interessieren, werde ich meinen aktuellen Ansatz hinzufügen, vielleicht findet ihn jemand nützlich. Der wahrscheinlich beste Weg wäre, wenn TH
-D
Parameter in der Befehlszeile von GHC lesen darf , aber es scheint, dass derzeit nichts dergleichen implementiert ist.Ein einfaches Modul ermöglicht es TH, die Umgebung zur Kompilierungszeit zu lesen. Eine Hilfsfunktion ermöglicht auch das Lesen von Dateien. Lesen Sie beispielsweise den Pfad einer Konfigurationsdatei aus der Umgebung und dann die Datei.
{-# LANGUAGE TemplateHaskell #-} module THEnv ( -- * Compile-time configuration lookupCompileEnv , lookupCompileEnvExp , getCompileEnv , getCompileEnvExp , fileAsString ) where import Control.Monad import qualified Data.Text as T import qualified Data.Text.IO as T import Language.Haskell.TH import Language.Haskell.TH.Syntax (Lift(..)) import System.Environment (getEnvironment) -- Functions that work with compile-time configuration -- | Looks up a compile-time environment variable. lookupCompileEnv :: String -> Q (Maybe String) lookupCompileEnv key = lookup key `liftM` runIO getEnvironment -- | Looks up a compile-time environment variable. The result is a TH -- expression of type @Maybe String@. lookupCompileEnvExp :: String -> Q Exp lookupCompileEnvExp = (`sigE` [t| Maybe String |]) . lift <=< lookupCompileEnv -- We need to explicly type the result so that things like `print Nothing` -- work. -- | Looks up an compile-time environment variable and fail, if it's not -- present. getCompileEnv :: String -> Q String getCompileEnv key = lookupCompileEnv key >>= maybe (fail $ "Environment variable " ++ key ++ " not defined") return -- | Looks up an compile-time environment variable and fail, if it's not -- present. The result is a TH expression of type @String@. getCompileEnvExp :: String -> Q Exp getCompileEnvExp = lift <=< getCompileEnv -- | Loads the content of a file as a string constant expression. -- The given path is relative to the source directory. fileAsString :: FilePath -> Q Exp fileAsString = do -- addDependentFile path -- works only with template-haskell >= 2.7 stringE . T.unpack . T.strip <=< runIO . T.readFile
Es kann folgendermaßen verwendet werden:
{-# LANGUAGE TemplateHaskell #-} import THEnv main = print $( lookupCompileEnvExp "DEBUG" )
Dann:
runhaskell Main.hs
DruckeNothing
;DEBUG="yes" runhaskell Main.hs
drucktJust "yes"
.quelle
Es sieht so aus, als ob Sie versuchen, dies hier zu tun . Die Option -D in ghc scheint eine Variable für die Kompilierungszeit zu definieren.
Hier ist zum gleichen Thema eine Frage , die auch den anderen Teil Ihrer Frage zu beantworten scheint. Nach allem, was ich sagen kann, machen Sie für die bedingte Kompilierung so etwas wie:
#ifdef MACRO_NAME //Do stuff here #endif
quelle
-D
Option wäre schön, wenn es eine Möglichkeit gäbe, sie in TH ohne CPP zu lesen.