-- This file comes from cabal-doctest: -- https://github.com/phadej/cabal-doctest/blob/master/simple-example -- -- It is needed so that doctest can be run with the same options as the modules -- are compiled with. {-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedLists #-} {-# OPTIONS_GHC -Wall #-} module Main (main) where import Data.Maybe (catMaybes) import Data.Monoid ((<>)) import Data.Version (Version) import Distribution.PackageDescription (HookedBuildInfo, cppOptions, emptyBuildInfo) import Distribution.Simple (UserHooks, defaultMainWithHooks, preBuild, preRepl, simpleUserHooks) import Distribution.Simple.Program (configureProgram, defaultProgramConfiguration, getDbProgramOutput, pkgConfigProgram) import Distribution.Text (simpleParse) import Distribution.Verbosity (normal) #ifndef MIN_VERSION_cabal_doctest #define MIN_VERSION_cabal_doctest(x,y,z) 0 #endif #if MIN_VERSION_cabal_doctest(1,0,0) import Distribution.Extra.Doctest (addDoctestsUserHook) main :: IO () main = do cppOpts <- getTermonadCPPOpts defaultMainWithHooks . addPkgConfigTermonadUserHook cppOpts $ addDoctestsUserHook "doctests" simpleUserHooks #else #ifdef MIN_VERSION_Cabal -- If the macro is defined, we have new cabal-install, -- but for some reason we don't have cabal-doctest in package-db -- -- Probably we are running cabal sdist, when otherwise using new-build -- workflow #warning You are configuring this package without cabal-doctest installed. \ The doctests test-suite will not work as a result. \ To fix this, install cabal-doctest before configuring. #endif main :: IO () main = do cppOpts <- getTermonadCPPOpts defaultMainWithHooks $ addPkgConfigTermonadUserHook cppOpts simpleUserHooks #endif -- | Add CPP macros representing the version of the GTK and VTE system -- libraries. addPkgConfigTermonadUserHook :: [String] -> UserHooks -> UserHooks addPkgConfigTermonadUserHook cppOpts oldUserHooks = do oldUserHooks { preBuild = pkgConfigTermonadHook cppOpts $ preBuild oldUserHooks , preRepl = pkgConfigTermonadHook cppOpts (preRepl oldUserHooks) } pkgConfigTermonadHook :: [String] -> (args -> flags -> IO HookedBuildInfo) -> args -> flags -> IO HookedBuildInfo pkgConfigTermonadHook cppOpts oldFunc args flags = do (maybeOldLibHookedInfo, oldExesHookedInfo) <- oldFunc args flags case maybeOldLibHookedInfo of Just oldLibHookedInfo -> do let newLibHookedInfo = oldLibHookedInfo { cppOptions = cppOptions oldLibHookedInfo <> cppOpts } pure (Just newLibHookedInfo, oldExesHookedInfo) Nothing -> do let newLibHookedInfo = emptyBuildInfo { cppOptions = cppOpts } pure (Just newLibHookedInfo, oldExesHookedInfo) getTermonadCPPOpts :: IO [String] getTermonadCPPOpts = do gtk <- getGtkVersionCPPOpts vte <- getVteVersionCPPOpts pure $ gtk <> vte getVteVersionCPPOpts :: IO [String] getVteVersionCPPOpts = do maybeVers <- getPkgConfigVersionFor "vte-2.91" case maybeVers of Nothing -> pure [] Just vers -> pure $ createVteVersionCPPOpts vers getGtkVersionCPPOpts :: IO [String] getGtkVersionCPPOpts = do maybeVers <- getPkgConfigVersionFor "gtk+-3.0" case maybeVers of Nothing -> pure [] Just vers -> pure $ createGtkVersionCPPOpts vers -- | Just like 'createGtkVersionCPPOpts' but for VTE instead of GTK. createVteVersionCPPOpts :: Version -> [String] createVteVersionCPPOpts vers = catMaybes $ [ if vers >= [0,44] then Just "-DVTE_VERSION_GEQ_0_44" else Nothing ] -- | Based on the version of the GTK3 library as reported by @pkg-config@, return -- a list of CPP macros that contain the GTK version. These can be used in the -- Haskell code to work around differences in the gi-gtk library Haskell -- library when compiled against different versions of the GTK system library. -- -- This list may need to be added to. createGtkVersionCPPOpts :: Version -- ^ 'Version' of the GTK3 library as reported by @pkg-config@. -> [String] -- ^ A list of CPP macros to show the GTK version. createGtkVersionCPPOpts gtkVersion = catMaybes $ [ if gtkVersion >= [3,22] then Just "-DGTK_VERSION_GEQ_3_22" else Nothing ] getPkgConfigVersionFor :: String -> IO (Maybe Version) getPkgConfigVersionFor program = do pkgDb <- configureProgram normal pkgConfigProgram defaultProgramConfiguration pkgConfigOutput <- getDbProgramOutput normal pkgConfigProgram pkgDb ["--modversion", program] -- Drop the newline on the end of the pkgConfigOutput. -- This should give us a version number like @3.22.11@. let rawProgramVersion = reverse $ drop 1 $ reverse pkgConfigOutput let maybeProgramVersion = simpleParse rawProgramVersion case maybeProgramVersion of Nothing -> do putStrLn $ "In Setup.hs, in getPkgConfigVersionFor, could not parse " <> program <> " version: " <> show pkgConfigOutput putStrLn $ "\nNot defining any CPP macros based on the version of the system " <> program <> " library." putStrLn "\nCompilation of termonad may fail." pure Nothing Just programVersion -> pure $ Just programVersion