GHC 版本签入代码
GHC version check in code
我正在为 Alex 做贡献,它显然依赖于很多库,应该针对很多版本进行编译。
我需要使用仅在 GHC 7.6.1 中可用的函数来更好地处理错误。所以我想使用 #if ...
来导入所述函数,否则,我将以不同的方式处理错误。
我看过一些:
#if __GLASGOW_HASKELL__ >= 610
import Control.Exception ( bracketOnError )
#endif
所以我做到了:
#if __GLASGOW_HASKELL__ >= 761
import Text.Read ( readMaybe )
#endif
认为 761
是 GHC 版本 7.6.1
的别名,当我构建 cabal 包并尝试它时,即使我使用 [=38],该函数也没有被导入=]The Glorious Glasgow Haskell编译系统,版本7.8.4.
于是用程序试了一下,发现7.8.1
在__GLASGOW_HASKELL__
中识别为708
。
{-# LANGUAGE CPP #-}
module Main where
#if __GLASGOW_HASKELL__ == 708
ver = "==708"
#else
ver = "/=708"
#endif
main = putStrLn $ ver
和运行它:
$ runhaskell if.hs
==708
我怎么知道我应该为 7.6.1
使用什么值,或者有更好的方法来处理这个问题吗?
For version x.y.z 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 (i.e. .hs, .lhs, .c and .hc files).
GHC 用户指南 section 6.11.3.1 中对此进行了描述:
For version x.y.z
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.
因此对于 7.6.1
,您将检查 __GLASGOW_HASKELL__ >= 706
。原因是像 7.10.x
.
这样的版本
正如 Daniel Wagner 指出的,检查包版本的最正确方法通常是使用 Cabal MIN_VERSION
宏。例如,您可以使用
#if MIN_VERSION_base(4,6,0)
确定base
包是否至少为4.6.0版本,即具有您查找的功能的最早版本。
base
包有点奇怪。它被 GHC 和现已解散的 Hugs 和 NHC 实现所使用。使用 Cabal 宏是检查 base
版本的一种更便携的方法。如今,GHC 是唯一使用 base
的方法,因此可移植性参数不太明确,但该方法也具有检查主要和次要版本号的优点。
由于 base
版本与 GHC 版本紧密相关,您可以定义 MIN_VERSION_base
的合理后备形式,以便在没有 Cabal 的情况下进行编译,使用 __GLASGOW_HASKELL__
来估计 base
版本。当前 containers
头有条件地定义了这样的回退。
更新
从 GHC 8 开始,编译器本身已经接管了定义 MIN_VERSION
宏的工作。这很棒,因为无论您是否使用 Cabal 构建,您现在都可以使用这些宏。不再有丑陋的近似值!
我正在为 Alex 做贡献,它显然依赖于很多库,应该针对很多版本进行编译。
我需要使用仅在 GHC 7.6.1 中可用的函数来更好地处理错误。所以我想使用 #if ...
来导入所述函数,否则,我将以不同的方式处理错误。
我看过一些:
#if __GLASGOW_HASKELL__ >= 610
import Control.Exception ( bracketOnError )
#endif
所以我做到了:
#if __GLASGOW_HASKELL__ >= 761
import Text.Read ( readMaybe )
#endif
认为 761
是 GHC 版本 7.6.1
的别名,当我构建 cabal 包并尝试它时,即使我使用 [=38],该函数也没有被导入=]The Glorious Glasgow Haskell编译系统,版本7.8.4.
于是用程序试了一下,发现7.8.1
在__GLASGOW_HASKELL__
中识别为708
。
{-# LANGUAGE CPP #-}
module Main where
#if __GLASGOW_HASKELL__ == 708
ver = "==708"
#else
ver = "/=708"
#endif
main = putStrLn $ ver
和运行它:
$ runhaskell if.hs
==708
我怎么知道我应该为 7.6.1
使用什么值,或者有更好的方法来处理这个问题吗?
For version x.y.z 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 (i.e. .hs, .lhs, .c and .hc files).
GHC 用户指南 section 6.11.3.1 中对此进行了描述:
For version
x.y.z
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.
因此对于 7.6.1
,您将检查 __GLASGOW_HASKELL__ >= 706
。原因是像 7.10.x
.
正如 Daniel Wagner 指出的,检查包版本的最正确方法通常是使用 Cabal MIN_VERSION
宏。例如,您可以使用
#if MIN_VERSION_base(4,6,0)
确定base
包是否至少为4.6.0版本,即具有您查找的功能的最早版本。
base
包有点奇怪。它被 GHC 和现已解散的 Hugs 和 NHC 实现所使用。使用 Cabal 宏是检查 base
版本的一种更便携的方法。如今,GHC 是唯一使用 base
的方法,因此可移植性参数不太明确,但该方法也具有检查主要和次要版本号的优点。
由于 base
版本与 GHC 版本紧密相关,您可以定义 MIN_VERSION_base
的合理后备形式,以便在没有 Cabal 的情况下进行编译,使用 __GLASGOW_HASKELL__
来估计 base
版本。当前 containers
头有条件地定义了这样的回退。
更新
从 GHC 8 开始,编译器本身已经接管了定义 MIN_VERSION
宏的工作。这很棒,因为无论您是否使用 Cabal 构建,您现在都可以使用这些宏。不再有丑陋的近似值!