Cross compiling with version 12 of mingw-w64 throws an error, where as version 9.3 works fine

81 Views Asked by At

I'm trying to cross compile some code (argtable-2.13, which I cannot change).

export cc_path="/usr"
export CFLAGS="-I${cc_path}/i686-w64-mingw32/include"
./configure --host=i686-w64-mingw32 --prefix=${cc_path}/i686-w64-mingw32
make CC=${cc_path}/bin/i686-w64-mingw32-gcc AR=${cc_path}/bin/i686-w64-mingw32-ar PREFIX=${cc_path}/i686-w64-mingw32 RANLIB=${cc_path}/bin/i686-w64-mingw32-ranlib LD={cc_path}/bin/i686-w64-mingw32-ld STRIP=${cc_path}/bin/i686-w64-mingw32-strip CXX=${cc_path}/bin/i686-w64-mingw32-g++

When I try compiling this code with mingw-w64 on Ubuntu 20.04 (version i686-w64-mingw32-gcc (GCC) 9.3-win32 20200320) it compiles just fine. But when I try the same with mingw-w64 on Ubuntu 23.10 (version i686-w64-mingw32-gcc (GCC) 12-win32), it throws an error.

/bin/i686-w64-mingw32-gcc -DHAVE_CONFIG_H -I. -I/i686-w64-mingw32/include -MT arg_int.lo -MD -MP -MF .deps/arg_int.Tpo -c arg_int.c  -DDLL_EXPORT -DPIC -o .libs/arg_int.o
In file included from /usr/lib/gcc/i686-w64-mingw32/12-win32/include/mm_malloc.h:29,
                 from /usr/share/mingw-w64/include/malloc.h:84,
                 from /usr/share/mingw-w64/include/stdlib.h:770,
                 from arg_int.c:28:
arg_int.c:35:37: error: expected identifier before numeric constant
   35 | enum {EMINCOUNT=1,EMAXCOUNT,EBADINT,EOVERFLOW};
      |                                     ^~~~~~~~~
arg_int.c: In function ‘strtol0X’:
arg_int.c:60:12: warning: implicit declaration of function ‘isspace’ [-Wimplicit-function-declaration]
   60 |     while (isspace(*ptr))
      |            ^~~~~~~
arg_int.c:33:1: note: include ‘<ctype.h>’ or provide a declaration of ‘isspace’
   32 | #include <limits.h>
  +++ |+#include <ctype.h>
   33 | 
arg_int.c:89:8: warning: implicit declaration of function ‘toupper’ [-Wimplicit-function-declaration]
   89 |    if (toupper(*ptr++)!=toupper(X))
      |        ^~~~~~~
arg_int.c:89:8: note: include ‘<ctype.h>’ or provide a declaration of ‘toupper’
make[2]: *** [Makefile:359: arg_int.lo] Error 1

I know why it's throwing an error since enum's cannot have the same name and somewhere with mingw-w64 v12 it's conflicting, but I can't change the code. It's including the file /usr/i686-w64-mingw32/include/errno.h which has an enum EOVERFLOW defined, but v 9.3 doesn't seem to complain where as v12 has a problem.

I've tried adding -std=c89 as an option but it doesn't make a difference.

How do I get mingw-w64 version 12 to behave like mingw-w64 version 9.3 in this regard?

1

There are 1 best solutions below

0
Lundin On

This was news to me, but it seems that errno.h is allowed to spew custom identifiers starting with E all over the standard namespace, as an implementation-defined feature.

C23 7.5:

Additional macro definitions, beginning with E and a digit or E and an uppercase letter, may also be specified by the implementation.

This is also mentioned in "future library directions". So some versions of the library may define stuff like EOVERFLOW as an implementation-defined feature.

Normally adding compiler options like -std=c11 -pedantic-errors would strip off non-standard identifiers from standard headers, but here it doesn't make a difference since standard C allows these identifiers to exist.

But notably this also means that such an implementation of errno.h cannot be used in strictly conforming programs.

The best work-around is not to use errno.h at all - it was always an archaic and poorly designed header, just as using a global error result variable was always bad design from a time long before multi-threading was invented. But sadly, lots of standard functions rely on errno so maybe that's not an option.

A possible work-around is just to do #undef EOVERFLOW, if you can't rename the enum.

As for why you get different results for different compiler versions, it may be that Mingw switched standard lib along the way. They used to use Microsoft's "CRT" standard lib, but I think(?) they switched out that one somewhere along the way.