cabal
cabal copied to clipboard
Regression over 3.6 concerning `ghc-options` `-pgmP` `-optP`
Phenomenon: The following incantation works on macOS with cabal-install
3.6, but not with the version from master
:
$ brew install cpp
$ cabal-3.6 install -w ghc-8.8.4 fudgets
With master
this gives an error about a rejected option -traditional
to the C compiler.
cc1: error: command-line option '-traditional' is valid for the driver but not for C
`gcc-11' failed in phase `C Compiler'. (Exit code: 1)
fugets.cabal
contains the following configuration line:
ghc-options: -pgmP cpp-11 -optP -traditional
This option might be propagated to the wrong place.
It should be investigated if this regression was caused by:
- #4439 (PRs: #7874 #7900)
I cannot reproduce this on Ubuntu, I think this is cpp-11
(clang, not gcc?) not working as the other variants, GCC doesn't seem to barf about -traditional
.
Which is weird, as there is no cpp-11
on my machine.
I don't know what fudgets
tries to do, but I'd blame them for doing something weird.
EDIT: I see, the whole snippet from fudgets.cabal
is
if os(darwin)
Extra-lib-dirs: /opt/X11/lib
Include-dirs: /opt/X11/include
-- Run 'brew install gcc', then you should have gcc-11 and cpp-11, or
-- possibly another version, in which case you need to adapt the line below:
if impl(ghc<8.10.3)
-- Use the -pgmP in ghc<8.10.3
ghc-options: -pgmP cpp-11 -optP -traditional
--else
-- Unfortunately -pgmP doesn't work in ghc>=8.10.3, so you need to
-- change a line in $PREFIX/lib/ghc-*/lib/settings insead:
-- ,("Haskell CPP command", "gcc-11")
You could try whether
touch foo.c
ghc -optP -traditional -v3 -c -o foo.o foo.c
# or/and
ghc -pgmP cpp-11 -optP -traditional -v3 -c -o foo.o foo.c
works on your machine.
I'm tempted to close this as "fudgets.cabal
" is broken.
Why they need to change c preprocessor and specify it to traditional? When compiling Haskell CPP is run in -traditional
by GHC (as otherwise it wouldn't work, cause standard CPP lexer is strict / non-compatible with Haskell). And C code can for sure be updated to not require -traditional
?
Thinking a bit more: GHC ought should have different flags for Haskell CPP and C CPP. Now they are the same pgmP
and optP
.
So I don't see how this can be fixed so "ghc-options
are respected when compiling C sources" and "fudgets author can specify CPP flags for Haskell code only". (The person who mentions that Cabal would invoke C compiler directly may try to discuss that with GHC developers, IIRC its a bad idea).
I figured the problem. It's indeed GHC-8.8.4 (and later, 8.10, 9.0, 9.2) issue.
ghc-8.8.4 -optP -traditional -v3 -c -o foo.o foo.c
*** C Compiler:
gcc -DTABLES_NEXT_TO_CODE -x c foo.c -o /tmp/ghc130297_0/ghc_1.s -no-pie -fno-PIC -Wimplicit -S -include /opt/ghc/8.8.4/lib/ghc-8.8.4/include/ghcversion.h -I/opt/ghc/8.8.4/lib/ghc-8.8.4/base-4.13.0.0/include -I/opt/ghc/8.8.4/lib/ghc-8.8.4/integer-gmp-1.0.2.0/include -I/opt/ghc/8.8.4/lib/ghc-8.8.4/include -Xpreprocessor -traditional
cc1: error: command line option ‘-traditional’ is valid for the driver but not for C
i.e. it passes optP
flags to GCC, ghc-8.6.5 didn't do that. So in away this a regression in GHC, but more precisely it's an issue I pointed in my previous comment.
I'd suggest @andreasabel to open GHC issue about this.
Great analysis, @phadej!
touch foo.c ghc -optP -traditional -v3 -c -o foo.o foo.c # or/and ghc -pgmP cpp-11 -optP -traditional -v3 -c -o foo.o foo.c
I can confirm that this works up to GHC 8.6, e.g.
*** C Compiler:
gcc ... -x c foo.c ...
But it breaks from GHC 8.8 upward, e.g.:
** C Compiler:
gcc -x c foo.c ... -Xpreprocessor -traditional
error: unknown argument: '-traditional'
I can also confirm that
cabal install -w ghc-8.6.5 fudgets
works even with cabal-install
from master
.
So the summary about cabal install fudgets
on macOS seems to be:
- With GHC 8.6 and below: works with "any"
cabal-install
- With GHC 8.8: works with 3.6 but not
master
- With GHC 8.10 and above: doesn't work with either
cabal-install
. (The author describes manual fixes that I haven't tried/am not interested in.)
I'd suggest @andreasabel to open GHC issue about this.
I found an upstream issue that looks related enough: https://gitlab.haskell.org/ghc/ghc/-/issues/17185
Here is a relevant comment from the discussion there (by @bgamari):
FWIW, @phadej and @hvr have considered changing
cabal check
such that it will warn on any .cabal file that defines a cpp-option (i.e., an-optP
flag) besides-D<VAR_NAME>=<VAR_VALUE>
.
That sounds a bit too heavy-handed to me. However, it would be reasonable to specifically forbid
-traditional
, for instance.
If that's mostly likely an upstream issue, let me remove the alarming label.
Fine with me. I think I put regression in 3.8
because of this item:
- With GHC 8.8: works with 3.6 but not
master