pier-0.2.0.0: src/Pier/Build/CFlags.hs
{-# LANGUAGE DeriveAnyClass #-}
module Pier.Build.CFlags
( TransitiveDeps(..)
, CFlags(..)
, getCFlags
, ghcDefines
) where
import Control.Applicative (liftA2)
import Control.Monad (guard)
import Data.Set (Set)
import Development.Shake
import Development.Shake.Classes
import Distribution.PackageDescription
import Distribution.System (buildOS, OS(OSX))
import Distribution.Text (display)
import Distribution.Types.PkgconfigDependency
import Distribution.Version (versionNumbers)
import GHC.Generics (Generic(..))
import qualified Data.Set as Set
import Pier.Build.Stackage
import Pier.Core.Artifact
data TransitiveDeps = TransitiveDeps
{ transitiveDBs :: Set Artifact
, transitiveLibFiles :: Set Artifact
, transitiveIncludeDirs :: Set Artifact
, transitiveDataFiles :: Set Artifact
} deriving (Show, Eq, Typeable, Generic, Hashable, Binary, NFData)
instance Semigroup TransitiveDeps where
(<>) = mappend
instance Monoid TransitiveDeps where
mempty = TransitiveDeps Set.empty Set.empty Set.empty Set.empty
TransitiveDeps dbs files is datas
`mappend` TransitiveDeps dbs' files' is' datas'
= TransitiveDeps (dbs <> dbs') (files <> files') (is <> is')
(datas <> datas')
-- TODO: macros file also
data CFlags = CFlags
{ ccFlags :: [String]
, cppFlags :: [String]
, cIncludeDirs :: Set Artifact
, linkFlags :: [String]
, linkLibs :: [String]
, macFrameworks :: [String]
}
-- TODO: include macros file too
getCFlags :: TransitiveDeps -> Artifact -> BuildInfo -> Action CFlags
getCFlags deps pkgDir bi = do
pkgConfFlags <- mconcat <$> mapM getPkgConfFlags (pkgconfigDepends bi)
return CFlags
{ ccFlags = ccOptions bi ++ fst pkgConfFlags
, cppFlags = cppOptions bi
, cIncludeDirs =
Set.fromList (map (pkgDir />) $ includeDirs bi)
<> transitiveIncludeDirs deps
, linkFlags = ldOptions bi ++ snd pkgConfFlags
, linkLibs = extraLibs bi
, macFrameworks = guard (buildOS == OSX)
>> frameworks bi
}
-- TODO: handle version numbers too
getPkgConfFlags :: PkgconfigDependency -> Action ([String], [String])
getPkgConfFlags (PkgconfigDependency name _) = liftA2 (,)
(runPkgConfig [display name, "--cflags"])
(runPkgConfig [display name, "--libs"])
where
runPkgConfig = fmap words . runCommandStdout . prog "pkg-config"
-- | Definitions that GHC provides by default
ghcDefines :: InstalledGhc -> [String]
ghcDefines ghc = ["-D__GLASGOW_HASKELL__=" ++
cppVersion (ghcInstalledVersion ghc)]
where
cppVersion v = case versionNumbers v of
(v1:v2:_) -> show v1 ++ if v2 < 10 then '0':show v2 else show v2
_ -> error $ "cppVersion: " ++ display v