Open andreasabel opened 1 year ago
Few comments, it's also GHC which defines MIN_VERSION_base
macros, e.g. given Ex.hs
{-# LANGUAGE CPP #-}
main :: IO ()
#if MIN_VERSION_base(4,19,0)
main = print True
#else
main = print False
#endif
we have
% runghc-9.8.1 Ex.hs
True
% runghc-9.6.2 Ex.hs
False
I don't know (or remember) why GHC defines them. Would be get to find out, and check if you'd also like/need to change GHC.
I'd prefer
#define SUPER_VERSION_base 4
#define MAJOR_VERSION_base 19
#define MINOR_VERSION_base 0
#define PATCH_VERSION_base 0
just because I likes justified identifiers :P
I'd appreciate if changes to cabal_macros.h
generation were explicitly part of the .cabal
format spec, i.e. to get new functionality, you'd need to use more recent cabal-version
.
And not having new features of cabal_macros.h
guarded behind cabal-version: ...
will result into issues like https://github.com/haskell/cabal/issues/9331
This is a reason why I think that cabal_macros.h
, Paths_pgkname.hs
generating code SHOULD be in Cabal-syntax
, as it's the package defining (most of) the file format.
Specifically, if something in Cabal-syntax
changes (say, new field) then there probably should be a new cabal-version
, and perfectly if we won't need to introduce new cabal-version:
(CabalVersionSpec
constructors) if nothing changes in Cabal-syntax
. The latter is exactly what happened leading to #9331: No change in Cabal-syntax
, so no-one thought about having new cabal-version
nor cabal-version
checks.
I was able to make this work by:
coan
(I tried unifdef
but it doesn't simplify conditional expressions)In the end I did something like this to remove all MIN_VERSION_ghc(9,2,*)
macros:
rg 'MIN_VERSION_ghc' -l | xargs -I {} bash -c "sed -i -e 's/MIN_VERSION_ghc(9,2,[0-9]*)/ALWAYS_TRUE/g' {} && coan source -r -DALWAYS_TRUE=1 {}"
I couldn't figure out a nice way to deal with __GLASGOW_HASKELL__ < 902
, though. Setting it to a particular value would also replace all other __GLASGOW_HASKELL__
comparisons.
The same trick with replacing particular comparisons with a constant would work, though, if the form is consistent enough in your codebase.
I looked into tools that could simplify my codebase by partially evaluating CPP conditionals. E.g. if I have
and I no longer support GHC < 8.6 or base < 4.11 then I can get rid of some cruft by partially evaluating the conditions and throw away the conditional together with the branch that is now impossible..
I checked some tools that do some partial evaluation of CPP conditionals:
unifdef
(shipped on my system macOS): https://dotat.at/prog/unifdef/cppp
: https://www.muppetlabs.com/~breadbox/software/cppp.htmlcoan
: https://coan2.sourceforge.net/index.phpThese tools typically only support setting a symbol to a value, like
__GLASGOW_HASKELL__=806
. They do not accept predicates, i.e., I cannot setMIN_VERSION_base(4,11,0)
to be true.So if Cabal defined 3 separate symbols to specify a version, instead of a ternary predicate, this would be compatible with such tools.
This would be usable in Haskell code as such:
(One could think of other macro names, like the triple
VERSION_EDITION_base
,VERSION_MAJOR_base
,VERSION_MINOR_base
---although the terminology edition for the "major-major" version is not established.)