Cabal-3.16.1.0: src/Distribution/Simple/Build/Macros.hs
-----------------------------------------------------------------------------
-- |
-- 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_<package>
-- > MIN_VERSION_<package>(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.
--
-- TODO Figure out what to do about backpack and internal libraries. It is very
-- suspicious that this stuff works with munged package identifiers
module Distribution.Simple.Build.Macros
( generateCabalMacrosHeader
, generatePackageVersionMacros
) where
import Distribution.Compat.Prelude
import Prelude ()
import Distribution.PackageDescription
import Distribution.Pretty
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.Program.Db
import Distribution.Simple.Program.Types
import Distribution.Types.MungedPackageId
import Distribution.Types.MungedPackageName
import Distribution.Version
import qualified Distribution.Simple.Build.Macros.Z as Z
-- | The contents of the @cabal_macros.h@ for the given configured package.
generateCabalMacrosHeader :: PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> String
generateCabalMacrosHeader pkg_descr lbi clbi =
Z.render
Z.Z
{ Z.zPackages = map mkZPackage $ package pkg_descr : map getPid (componentPackageDeps clbi)
, Z.zTools =
[ Z.ZTool
{ Z.ztoolName = programId prog
, Z.ztoolVersion = ver
, Z.ztoolX = major1
, Z.ztoolY = major2
, Z.ztoolZ = minor
}
| prog <- configuredPrograms $ withPrograms lbi
, ver <- maybeToList (programVersion prog)
, let (major1, major2, minor) = majorMinor ver
]
, Z.zPackageKey = case clbi of
LibComponentLocalBuildInfo{componentCompatPackageKey = compatPackageKey} -> compatPackageKey
_ -> ""
, Z.zComponentId = prettyShow (componentComponentId clbi)
, Z.zPackageVersion = pkgVersion (package pkg_descr)
, Z.zNotNull = not . null
, Z.zManglePkgName = map fixchar . unPackageName
, Z.zMangleStr = map fixchar
}
where
getPid (_, MungedPackageId (MungedPackageName pn _) v) =
-- NB: Drop the library name! We're just reporting package versions.
-- This would have to be revisited if you are allowed to depend
-- on different versions of the same package
PackageIdentifier pn v
-- | 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 :: Version -> [PackageId] -> String
generatePackageVersionMacros ver pkgids =
Z.render
Z.Z
{ Z.zPackages = map mkZPackage pkgids
, Z.zTools = []
, Z.zPackageKey = ""
, Z.zComponentId = ""
, Z.zPackageVersion = ver
, Z.zNotNull = not . null
, Z.zManglePkgName = map fixchar . unPackageName
, Z.zMangleStr = map fixchar
}
mkZPackage :: PackageId -> Z.ZPackage
mkZPackage (PackageIdentifier name ver) =
Z.ZPackage
{ Z.zpkgName = name
, Z.zpkgVersion = ver
, Z.zpkgX = major1
, Z.zpkgY = major2
, Z.zpkgZ = minor
}
where
(major1, major2, minor) = majorMinor ver
majorMinor :: Version -> (String, String, String)
majorMinor ver = case map show (versionNumbers ver) of
[] -> ("0", "0", "0")
[x] -> (x, "0", "0")
[x, y] -> (x, y, "0")
(x : y : z : _) -> (x, y, z)
fixchar :: Char -> Char
fixchar '-' = '_'
fixchar c = c