Cabal, or more recently GHC itself, pre-defines CPP macros that allow checking what version of which library is used. It works easily in simple examples like
#if MIN_VERSION_base(4,0,0)
... code that works with base-4 ...
#else
... code that works with base-3 ...
#endif
However, CPP macro names are more restricted than Cabal package names, so the following does not work:
#if !MIN_VERSION_quickcheck-instances(0,3,17)
instance Arbitrary SBS.ShortByteString where arbitrary = fmap SBS.pack arbitrary
#endif
error: missing binary operator before token "(" #if !MIN_VERSION_quickcheck-instances(0,3,17) ^ | 18 | #if !MIN_VERSION_quickcheck-instances(0,3,17) | ^ `gcc' failed in phase `C pre-processor'. (Exit code: 1)
It doesn't seem to be properly documented how library names like this are handled.
Short answer: the hyphen (-
) is replaced with an underscore (_
).
The macros are - as far as I know - generated in the generatePackageVersionMacros
function of the DriverPipeline.hs
file:
generatePackageVersionMacros :: [PackageConfig] -> String generatePackageVersionMacros pkgs = concat -- Do not add any C-style comments. See Trac #3389. [ generateMacros "" pkgname version | pkg <- pkgs , let version = packageVersion pkg pkgname = map fixchar (packageNameString pkg) ] fixchar :: Char -> Char fixchar '-' = '_' fixchar c = c generateMacros :: String -> String -> Version -> String generateMacros prefix name version = concat ["#define ", prefix, "VERSION_",name," ",show (showVersion 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)
As you can see the packageNameString
of the package is fixed by performing a map fixchar
on it. The hyphen (-
) is replaced with an underscore (_
). The macro can thus be written like:
#if !MIN_VERSION_quickcheck_instances(0,3,17)
instance Arbitrary SBS.ShortByteString where arbitrary = fmap SBS.pack arbitrary
#endif
You can check the generated macros in dist/build/autogen/cabal_macros.h
.
The macro for quickcheck-instances
would be named MIN_VERSION_quickcheck_instances
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With