{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} module GHC.Check.Internal where import Control.Monad.Trans.Class as Monad (MonadTrans (lift)) import Data.Maybe (fromMaybe) import Data.String (IsString (fromString)) import Data.Version (Version) import GHC import GHC.Exts (IsList (fromList), toList) import qualified GHC.Paths import Language.Haskell.TH import Language.Haskell.TH.Syntax as TH (TExp(TExp), lift) import Maybes (MaybeT (MaybeT), runMaybeT) import Module (componentIdToInstalledUnitId) import PackageConfig (PackageName (PackageName)) import Packages (lookupInstalledPackage, lookupPackageName) import Packages (InstalledPackageInfo (packageVersion)) import System.Environment (lookupEnv) -- | Look up the GHC lib dir in the NIX environment, then in the 'GHC.Paths' guessLibdir :: IO FilePath guessLibdir = fromMaybe GHC.Paths.libdir <$> lookupEnv "NIX_GHC_LIBDIR" getPackageVersion :: String -> Ghc (Maybe Version) getPackageVersion packageName = runMaybeT $ do dflags <- Monad.lift getSessionDynFlags component <- MaybeT $ return $ lookupPackageName dflags $ PackageName $ fromString packageName p <- MaybeT $ return $ lookupInstalledPackage dflags (componentIdToInstalledUnitId component) return $ packageVersion p getGhcVersion :: Ghc (Maybe Version) getGhcVersion = getPackageVersion "ghc" getGhcVersionIO :: FilePath -> IO Version getGhcVersionIO libdir = runGhc (Just libdir) $ do dflags <- getSessionDynFlags _ <- setSessionDynFlags dflags ghcV <- getGhcVersion case ghcV of Just v -> return v Nothing -> error "Cannot get version of ghc package" -- | Returns the compile-time version of the 'ghc' package given the GHC libdir compileTimeVersionFromLibdir :: IO FilePath -> TExpQ Version compileTimeVersionFromLibdir getLibdir = do ver <- runIO $ do libdir <- getLibdir v <- getGhcVersionIO libdir return (toList v) verLifted <- TH.lift (toList ver) [|| fromList $$(pure $ TExp verLifted) ||]