GHC version check in code
I'm contributing to Alex, and it obviously depends on a lot of libraries and should compile for a lot of versions.
I need to use a function that is only available from GHC 7.6.1 to handle an error better. So I want to use an #if ...
to import said function, else, I'll deal with the error differently.
I've seen some:
#if __GLASGOW_HASKELL__ >= 610
import Control.Exception ( bracketOnError )
#endif
So I did:
#if __GLASGOW_HASKELL__ >= 761
import Text.Read ( readMaybe )
#endif
Thinking that 761
is an alias to GHC version 7.6.1
, when I build the cabal package and try it out, the function doesn't get imported, even though I use The Glorious Glasgow Haskell Compilation System, version 7.8.4 .
So after using a program to try it out, I find out that 7.8.1
identifies in __GLASGOW_HASKELL__
as 708
.
{-# LANGUAGE CPP #-}
module Main where
#if __GLASGOW_HASKELL__ == 708
ver = "==708"
#else
ver = "/=708"
#endif
main = putStrLn $ ver
And running it:
$ runhaskell if.hs
==708
How can I know what value should I use for 7.6.1
, or is there a better way to deal with this?
That's described in section 6.11.3.1 of GHC's users guide:
For version xyz
of GHC, the value of __GLASGOW_HASKELL__
is the integer ⟨xyy⟩ (if ⟨y⟩ is a single digit, then a leading zero is added, so for example in version 6.2 of GHC, __GLASGOW_HASKELL__==602
). More information in GHC version numbering policy.
So for 7.6.1
, you would check __GLASGOW_HASKELL__ >= 706
. The reason for this are versions like 7.10.x
.
Read the fine documentation:
For version xyz of GHC, the value of __GLASGOW_HASKELL__
is the integer xyy (if y is a single digit, then a leading zero is added, so for example in version 6.2 of GHC, __GLASGOW_HASKELL__
==602). More information in Section 1.4, “GHC version numbering policy”.
With any luck, __GLASGOW_HASKELL__
will be undefined in all other implementations that support C-style pre-processing.
(For reference: the comparable symbols for other systems are: __HUGS__
for Hugs, __NHC__
for nhc98, and __HBC__
for hbc.)
NB. This macro is set when pre-processing both Haskell source and C source, including the C source generated from a Haskell module (ie .hs, .lhs, .c and .hc files).
As Daniel Wagner indicated, the most correct way to check for package version is usually to use a Cabal MIN_VERSION
macro. For example, you could use
#if MIN_VERSION_base(4,6,0)
to determine if the base
package is at least version 4.6.0, which is the earliest version with the function you seek.
The base
package is a little weird. It was used both by GHC and by the now-defunct Hugs and NHC implementations. Using the Cabal macro was then a more portable way to check the base
version. These days, GHC is the only one using base
, so the portability argument is a little less clear, but that approach also has the advantage of checking the major and minor version numbers.
Since base
versions are very tightly tied to GHC versions, you can define a reasonable fall-back form of MIN_VERSION_base
for compiling without Cabal, using __GLASGOW_HASKELL__
to estimate the base
version. The current containers
head conditionally defines such a fall-back.
Update
As of GHC 8, the compiler itself has taken over the job of defining MIN_VERSION
macros. This is great, because you now get to use these macros whether or not you build with Cabal. No more ugly approximations!
上一篇: 为什么不睡觉工作?
下一篇: GHC版本检入代码