----------------------------------------------------------------------------- -- | -- Module : Distribution.Simple.Build.Macros -- Copyright : Simon Marlow 2008 -- -- Maintainer : cabal-devel@haskell.org -- Portability : portable -- -- Generate cabal_macros.h - CPP macros for package version testing -- -- When using CPP you get -- -- > VERSION_ -- > MIN_VERSION_(A,B,C) -- -- for each /package/ in @build-depends@, which is true if the version of -- /package/ in use is @>= A.B.C@, using the normal ordering on version -- numbers. -- module Distribution.Simple.Build.Macros ( generate, generatePackageVersionMacros, ) where import Data.Maybe ( isJust ) import Distribution.Package ( PackageIdentifier(PackageIdentifier) ) import Distribution.Version ( Version(versionBranch) ) import Distribution.PackageDescription ( PackageDescription ) import Distribution.Simple.Compiler ( packageKeySupported ) import Distribution.Simple.LocalBuildInfo ( LocalBuildInfo(compiler, pkgKey, withPrograms), externalPackageDeps ) import Distribution.Simple.Program.Db ( configuredPrograms ) import Distribution.Simple.Program.Types ( ConfiguredProgram(programId, programVersion) ) import Distribution.Text ( display ) -- ------------------------------------------------------------ -- * Generate cabal_macros.h -- ------------------------------------------------------------ -- | The contents of the @cabal_macros.h@ for the given configured package. -- generate :: PackageDescription -> LocalBuildInfo -> String generate _pkg_descr lbi = "/* DO NOT EDIT: This file is automatically generated by Cabal */\n\n" ++ generatePackageVersionMacros (map snd (externalPackageDeps lbi)) ++ generateToolVersionMacros (configuredPrograms . withPrograms $ lbi) ++ generatePackageKeyMacro lbi -- | Helper function that generates just the @VERSION_pkg@ and @MIN_VERSION_pkg@ -- macros for a list of package ids (usually used with the specific deps of -- a configured package). -- generatePackageVersionMacros :: [PackageIdentifier] -> String generatePackageVersionMacros pkgids = concat [ "/* package " ++ display pkgid ++ " */\n" ++ generateMacros "" pkgname version | pkgid@(PackageIdentifier name version) <- pkgids , let pkgname = map fixchar (display name) ] -- | Helper function that generates just the @TOOL_VERSION_pkg@ and -- @MIN_TOOL_VERSION_pkg@ macros for a list of configured programs. -- generateToolVersionMacros :: [ConfiguredProgram] -> String generateToolVersionMacros progs = concat [ "/* tool " ++ progid ++ " */\n" ++ generateMacros "TOOL_" progname version | prog <- progs , isJust . programVersion $ prog , let progid = programId prog ++ "-" ++ display version progname = map fixchar (programId prog) Just version = programVersion prog ] -- | Common implementation of 'generatePackageVersionMacros' and -- 'generateToolVersionMacros'. -- generateMacros :: String -> String -> Version -> String generateMacros prefix name version = concat ["#define ", prefix, "VERSION_",name," ",show (display version),"\n" ,"#define MIN_", prefix, "VERSION_",name,"(major1,major2,minor) (\\\n" ," (major1) < ",major1," || \\\n" ," (major1) == ",major1," && (major2) < ",major2," || \\\n" ," (major1) == ",major1," && (major2) == ",major2," && (minor) <= ",minor,")" ,"\n\n" ] where (major1:major2:minor:_) = map show (versionBranch version ++ repeat 0) -- | Generate the @CURRENT_PACKAGE_KEY@ definition for the package key -- of the current package, if supported by the compiler generatePackageKeyMacro :: LocalBuildInfo -> String generatePackageKeyMacro lbi | packageKeySupported (compiler lbi) = "#define CURRENT_PACKAGE_KEY \"" ++ display (pkgKey lbi) ++ "\"\n\n" | otherwise = "" fixchar :: Char -> Char fixchar '-' = '_' fixchar c = c