c2hs icon indicating copy to clipboard operation
c2hs copied to clipboard

when biulding ncurses: The symbol `can_change_color' does not fit here.

Open jwaldmann opened this issue 7 months ago • 9 comments

when building ncurses-0.2.16, I get

cabal install
...
c2hs: C header contains errors:

/usr/include/curses.h:638: (column 13) [ERROR]  >>> Syntax error !
  The symbol `can_change_color' does not fit here.

now ncurses seems unmaintained, but the error might be with c2hs?

(note: similar error message in #290)

the offending lines of curses.h are

    636 extern NCURSES_EXPORT(int) border (chtype,chtype,chtype,chtype,chtype,chtype,chtype,chtype);    /* generated */
    637 extern NCURSES_EXPORT(int) box (WINDOW *, chtype, chtype);              /* generated */
    638 extern NCURSES_EXPORT(bool) can_change_color (void);                    /* implemented */
    639 extern NCURSES_EXPORT(int) cbreak (void);                               /* implemented */
    640 extern NCURSES_EXPORT(int) chgat (int, attr_t, NCURSES_PAIRS_T, const void *);  /* generated */
    641 extern NCURSES_EXPORT(int) clear (void);                                /* generated */

this gets translated (I did gcc -E) to

extern int border (chtype,chtype,chtype,chtype,chtype,chtype,chtype,chtype);
extern int box (WINDOW *, chtype, chtype);
extern bool can_change_color (void);
extern int cbreak (void);
extern int chgat (int, attr_t, short, const void *);
extern int clear (void);

this is the first occurence of bool, perhaps c2hs doesn't know this type name?

jwaldmann avatar Apr 21 '25 11:04 jwaldmann

I am having the same issue now with opendht-hs. It used to build without issue as you can see from this build report:

https://github.com/sim590/opendht-hs/actions/runs/14013940100/job/39237185867

Now, I'm getting this when running cabal v2-build --c2hs-options="-d trace":

Output
Build profile: -w ghc-9.4.8 -O1
In order, the following will be built (use -v for more details):
 - opendht-hs-0.1.0.0 (lib) (first run)
Preprocessing library for opendht-hs-0.1.0.0...
Attempting to read file `src/OpenDHT/Internal/InfoHash.chs'...
...parsing `src/OpenDHT/Internal/InfoHash'...
...successfully loaded `src/OpenDHT/Internal/InfoHash'.
Invoking cpp as `/usr/bin/gcc -x c -E -D__GLASGOW_HASKELL__=904 -Dlinux_BUILD_OS=1 -Dx86_64_BUILD_ARCH=1 -Dlinux_HOST_OS=1 -Dx86_64_HOST_ARCH=1 -Isrc/OpenDHT/Internal -I/usr/include -I/usr/include/p11-kit-1 -include/home/simon/prog/opendht-hs/dist-newstyle/build/x86_64-linux/ghc-9.4.8/opendht-hs-0.1.0.0/build/autogen/cabal_macros.h -I/home/simon/.cabal/store/ghc-9.4.8/vector-0.13.2.0-6aae70b3816ec4c6a7eb3d9c6baec7cf17ab00d1f1972c3394b171241770e8e6/lib//include -I/home/simon/.cabal/store/ghc-9.4.8/primitive-0.9.0.0-49fd112f793c9f23b35ca43b8873ca993b3d61ee5badbbebe3a532a2fc29ec42/lib//include -I/home/simon/.ghcup/ghc/9.4.8/lib/ghc-9.4.8/lib/../lib/x86_64-linux-ghc-9.4.8/bytestring-0.11.5.3/include -I/home/simon/.ghcup/ghc/9.4.8/lib/ghc-9.4.8/lib/../lib/x86_64-linux-ghc-9.4.8/base-4.17.2.1/include -I/home/simon/.ghcup/ghc/9.4.8/lib/ghc-9.4.8/lib/../lib/x86_64-linux-ghc-9.4.8/ghc-bignum-1.3/include -I/home/simon/.ghcup/ghc/9.4.8/lib/ghc-9.4.8/lib/../lib/x86_64-linux-ghc-9.4.8/rts-1.0.2/include -U__BLOCKS__ -DC2HS_VERSION_MAJOR=0 -DC2HS_VERSION_MINOR=28 -DC2HS_VERSION_REV=8 /home/simon/prog/opendht-hs/dist-newstyle/build/x86_64-linux/ghc-9.4.8/opendht-hs-0.1.0.0/build/OpenDHT/Internal/InfoHash.chs.h'...
Attempting to read file `/home/simon/prog/opendht-hs/dist-newstyle/build/x86_64-linux/ghc-9.4.8/opendht-hs-0.1.0.0/build/OpenDHT/Internal/InfoHash.i'...
...parsing `/home/simon/prog/opendht-hs/dist-newstyle/build/x86_64-linux/ghc-9.4.8/opendht-hs-0.1.0.0/build/OpenDHT/Internal/InfoHash.i'...
...name analysis of `/home/simon/prog/opendht-hs/dist-newstyle/build/x86_64-linux/ghc-9.4.8/opendht-hs-0.1.0.0/build/OpenDHT/Internal/InfoHash.i'...
...error(s) detected in `/home/simon/prog/opendht-hs/dist-newstyle/build/x86_64-linux/ghc-9.4.8/opendht-hs-0.1.0.0/build/OpenDHT/Internal/InfoHash.i'.
c2hs: C header contains errors:

/usr/include/opendht/opendht_c.h:57: (column 7) [ERROR]  >>> Syntax error !
  The symbol `dht_infohash_is_zero' does not fit here.

Error: [Cabal-7125]
Failed to build opendht-hs-0.1.0.0.

Looking at the file InfoHash.i, I can see that it seems to choke on this line:

OPENDHT_C_PUBLIC bool dht_infohash_is_zero(const dht_infohash* h);

When, I tried to remove that line and recompile the C library, I saw that it then choked on another function name that had bool as a return type. This is odd, as the file has not changed at all since last compilation with c2hs and #include <stdbool.h> is included.

I saw that c2hs was using GCC, so I tried installing the version of GCC before my last update on my system and it actually fixed it.

So, it seems like the issue appeared between GCC 14.2.1 (which works) and GCC 15.1.1 (which doesn't work).

On Archlinux, the actual packages versions are respectively 14.2.1+r753+g1cd744a6828f and 15.1.1+r7+gf36ec88aa85a-1.

I have not tried bisecting GCC to get the exact version. If it would help, then I could do it later.

So, either this is a new change in GCC which requires us to add extra flags for our compilation commands for that to work, or this is a GCC bug.

sim590 avatar May 01 '25 17:05 sim590

An additional thing that is of interest here, is that folks over here:

https://github.com/ArbiterLib/Arbiter/pull/66

had an issue in 2016 (9 years ago) which seemed to be the same as the one we have now, but it must be different as the difference in versions of GCC causing the behaviour change makes me doubt that we would have the exact same issue. But may be it's something that occurred 9 years ago and came back. I don't know.

sim590 avatar May 01 '25 18:05 sim590

Could the changes listed in the changelog of GCC 15.1 explain what we are seeing:

https://gcc.gnu.org/gcc-15/changes.html#c

I was drawn to this line particularly:

To aid the transition to C23, various diagnostics have been enhanced to clarify type errors such as incompatible function types, incorrect argument counts, and those involving bool.

Not sure, though. I thought it was related because of bool and incompatible function types. I don't know.

sim590 avatar May 01 '25 18:05 sim590

ah, nice find. then a work-around could be

  • use gcc<15
  • with gcc-15: disable some warnings
  • e.g. by -std=something ancient

jwaldmann avatar May 01 '25 18:05 jwaldmann

@jwaldmann:

e.g. by -std=something ancient

I think that this would be the best from the point of view of our projects as there would be no consequences on the users of the libraries that we develop.

I tested the following and it works:

cabal v2-build --c2hs-options="--cppopts=--std=gnu18"

So, gnu18 or gnu17 (which seems to be an alias) is the actual default for GCC 14.

So, for opendht-hs, I will add the following:

-- File: cabal.project
pacakges: .

package opendht-hs
  c2hs-options: -C -std=gnu18

I would suggest a change similar to this inside ncurses for the sake of its users.

sim590 avatar May 01 '25 20:05 sim590

Regarding my last comment, I just realized an issue. The cabal.project file doesn't ship with cabal sdist archives, so when uploading a package to hackage, the workaround is not propagated... Also, c2hs-options field is not recognized by *.cabal file parser unlike other fields such as hsch2s-options. I need to open an issue on cabal about this so that we can get a workaround that ships in packages.

sim590 avatar May 02 '25 15:05 sim590

c2hs' test suite fails here with a lot of errors too, I think this is the first cause:

DEBUG:root:c2hs: Exception: error running: cc -o structs_c.o -c structs.c
DEBUG:root:c2hs: exit status: 1
DEBUG:root:c2hs: stderr: In file included from structs.c:3:
DEBUG:root:c2hs: structs.h:4:14: error: ‘bool’ cannot be defined via ‘typedef’
DEBUG:root:c2hs:     4 | typedef char bool, mychar;
DEBUG:root:c2hs:       |              ^~~~
DEBUG:root:c2hs: structs.h:4:14: note: ‘bool’ is a keyword with ‘-std=c23’ onwards
DEBUG:root:c2hs: structs.h:4:18: error: expected identifier or ‘(’ before ‘,’ token
DEBUG:root:c2hs:     4 | typedef char bool, mychar;
DEBUG:root:c2hs:       |                  ^
DEBUG:root:c2hs: structs.h:34:1: error: unknown type name ‘mychar’; did you mean ‘u_char’?
DEBUG:root:c2hs:    34 | mychar *getSpacePtr (void);
DEBUG:root:c2hs:       | ^~~~~~
DEBUG:root:c2hs:       | u_char
DEBUG:root:c2hs: structs.c:28:1: error: unknown type name ‘mychar’; did you mean ‘u_char’?
DEBUG:root:c2hs:    28 | mychar *getSpacePtr (void)
DEBUG:root:c2hs:       | ^~~~~~
DEBUG:root:c2hs:       | u_char
DEBUG:root:c2hs: structs.c: In function ‘getSpacePtr’:
DEBUG:root:c2hs: structs.c:32:10: error: returning ‘char *’ from a function with incompatible return type ‘int *’ [-Wincompatible-pointer-types]
DEBUG:root:c2hs:    32 |   return &c;
DEBUG:root:c2hs:       |          ^~

felixonmars avatar May 05 '25 05:05 felixonmars

@felixonmars: have you checked if GCC 14 or 15 was used while compiling the test suite?

sim590 avatar May 05 '25 18:05 sim590

GCC 15 was used, so I am replying here because I think it's the same issue.

felixonmars avatar May 06 '25 01:05 felixonmars