Discussion:
Gnulib's wctype.h fails to compile with MinGW
Eli Zaretskii
2017-04-27 14:44:58 UTC
Permalink
Building the recent pretest of Texinfo 6.4 with mingw.org's MinGW
fails:

gcc -static-libgcc -DHAVE_CONFIG_H -I. -I../.. -Id:/usr/include -O2 -gdwarf-4 -g3 -MT mbchar.o -MD -MP -MF $depbase.Tpo -c -o mbchar.o mbchar.c &&\
mv -f $depbase.Tpo $depbase.Po
In file included from d:\usr\include\wchar.h:44:0,
from ./wchar.h:87,
from mbchar.h:156,
from mbchar.c:23:
./wctype.h:539:24: fatal error: crtdefs.h: No such file or directory
compilation terminated.
Makefile:1399: recipe for target `mbchar.o' failed
make[4]: *** [mbchar.o] Error 1

This happens because gnulib/lib/wctype.h does this:

#else
/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h>.
This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be
"unchanged by default argument promotions". Override it. */
# if 1
# if !GNULIB_defined_wint_t
# include <crtdefs.h>
typedef unsigned int rpl_wint_t;
# undef wint_t
# define wint_t rpl_wint_t
# define GNULIB_defined_wint_t 1
# endif
# endif

But mingw.org's MinGW headers don't have crtdefs.h. The wint_t type
is defined in stddef.h there.

I propose the following to fix this:

diff --git a/lib/wctype.in.h b/lib/wctype.in.h
index d307630..70bd4d2 100644
--- a/lib/wctype.in.h
+++ b/lib/wctype.in.h
@@ -105,12 +105,21 @@ _GL_INLINE_HEADER_BEGIN
# define WEOF -1
# endif
#else
-/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h>.
+/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h>/<stddef.h>.
This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be
"unchanged by default argument promotions". Override it. */
# if @GNULIB_OVERRIDES_WINT_T@
# if !GNULIB_defined_wint_t
-# include <crtdefs.h>
+# ifdef __MINGW32__
+# include <_mingw.h>
+# ifdef __MINGW64_VERSION_MAJOR
+# include <crtdefs.h>
+# else
+# include <stddef.h>
+# endif
+# else
+# include <crtdefs.h>
+# endif
typedef unsigned int rpl_wint_t;
# undef wint_t
# define wint_t rpl_wint_t
Bruno Haible
2017-04-27 17:03:35 UTC
Permalink
Hi Eli,
Post by Eli Zaretskii
Building the recent pretest of Texinfo 6.4 with mingw.org's MinGW
gcc -static-libgcc -DHAVE_CONFIG_H -I. -I../.. -Id:/usr/include -O2 -gdwarf-4 -g3 -MT mbchar.o -MD -MP -MF $depbase.Tpo -c -o mbchar.o mbchar.c &&\
mv -f $depbase.Tpo $depbase.Po
In file included from d:\usr\include\wchar.h:44:0,
from ./wchar.h:87,
from mbchar.h:156,
./wctype.h:539:24: fatal error: crtdefs.h: No such file or directory
compilation terminated.
Makefile:1399: recipe for target `mbchar.o' failed
make[4]: *** [mbchar.o] Error 1
#else
/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h>.
This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be
"unchanged by default argument promotions". Override it. */
# if 1
# if !GNULIB_defined_wint_t
# include <crtdefs.h>
typedef unsigned int rpl_wint_t;
# undef wint_t
# define wint_t rpl_wint_t
# define GNULIB_defined_wint_t 1
# endif
# endif
But mingw.org's MinGW headers don't have crtdefs.h. The wint_t type
is defined in stddef.h there.
diff --git a/lib/wctype.in.h b/lib/wctype.in.h
index d307630..70bd4d2 100644
--- a/lib/wctype.in.h
+++ b/lib/wctype.in.h
@@ -105,12 +105,21 @@ _GL_INLINE_HEADER_BEGIN
# define WEOF -1
# endif
#else
-/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h>.
+/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h>/<stddef.h>.
This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be
"unchanged by default argument promotions". Override it. */
# if !GNULIB_defined_wint_t
-# include <crtdefs.h>
+# ifdef __MINGW32__
+# include <_mingw.h>
+# ifdef __MINGW64_VERSION_MAJOR
+# include <crtdefs.h>
+# else
+# include <stddef.h>
+# endif
+# else
+# include <crtdefs.h>
+# endif
typedef unsigned int rpl_wint_t;
# undef wint_t
# define wint_t rpl_wint_t
Thanks for the report and suggested fix.

The #ifdefology here seems a bit fragile to me (will likely break in other
forks of mingw), therefore I'm using an Autoconf test instead:


2017-04-27 Bruno Haible <***@clisp.org>

wctype-h: Fix compilation error with the original mingw.org mingw.
* m4/wctype_h.m4 (gl_WCTYPE_H): Test for <crtdefs.h>. Set
HAVE_CRTDEFS_H.
* modules/wctype-h (Makefile.am): Substitute HAVE_CRTDEFS_H.
* lib/wctype.in.h (rpl_wint_t): If <crtdefs.h> does not exist, include
<stddef.h> instead.
Reported and proposed by Eli Zaretskii <***@gnu.org>.

diff --git a/lib/wctype.in.h b/lib/wctype.in.h
index d307630..933bf78 100644
--- a/lib/wctype.in.h
+++ b/lib/wctype.in.h
@@ -105,12 +105,16 @@ _GL_INLINE_HEADER_BEGIN
# define WEOF -1
# endif
#else
-/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h>.
- This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be
- "unchanged by default argument promotions". Override it. */
+/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h> or
+ <stddef.h>. This is too small: ISO C 99 section 7.24.1.(2) says that
+ wint_t must be "unchanged by default argument promotions". Override it. */
# if @GNULIB_OVERRIDES_WINT_T@
# if !GNULIB_defined_wint_t
-# include <crtdefs.h>
+# if @HAVE_CRTDEFS_H@
+# include <crtdefs.h>
+# else
+# include <stddef.h>
+# endif
typedef unsigned int rpl_wint_t;
# undef wint_t
# define wint_t rpl_wint_t
diff --git a/m4/wctype_h.m4 b/m4/wctype_h.m4
index 45ddaeb..c72a73f 100644
--- a/m4/wctype_h.m4
+++ b/m4/wctype_h.m4
@@ -1,4 +1,4 @@
-# wctype_h.m4 serial 18
+# wctype_h.m4 serial 19

dnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it.

@@ -66,6 +66,14 @@ AC_DEFUN([gl_WCTYPE_H],
fi
AC_SUBST([HAVE_WCTYPE_H])

+ AC_CHECK_HEADERS_ONCE([crtdefs.h])
+ if test $ac_cv_header_crtdefs_h = yes; then
+ HAVE_CRTDEFS_H=1
+ else
+ HAVE_CRTDEFS_H=0
+ fi
+ AC_SUBST([HAVE_CRTDEFS_H])
+
case "$gl_cv_func_iswcntrl_works" in
*yes) REPLACE_ISWCNTRL=0 ;;
*) REPLACE_ISWCNTRL=1 ;;
diff --git a/modules/wctype-h b/modules/wctype-h
index adfb218..37bccce 100644
--- a/modules/wctype-h
+++ b/modules/wctype-h
@@ -31,6 +31,7 @@ wctype.h: wctype.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(WARN_ON_USE_H
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
-e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \
+ -e 's/@''HAVE_CRTDEFS_H''@/$(HAVE_CRTDEFS_H)/g' \
-e 's/@''GNULIB_OVERRIDES_WINT_T''@/$(GNULIB_OVERRIDES_WINT_T)/g' \
-e 's/@''GNULIB_ISWBLANK''@/$(GNULIB_ISWBLANK)/g' \
-e 's/@''GNULIB_WCTYPE''@/$(GNULIB_WCTYPE)/g' \
Eli Zaretskii
2017-04-27 17:50:25 UTC
Permalink
Date: Thu, 27 Apr 2017 19:03:35 +0200
Thanks for the report and suggested fix.
The #ifdefology here seems a bit fragile to me (will likely break in other
I only know of 2 flavors of MinGW (and wish there were only one), but
of course an Autoconf test is even better. Thanks.

Gavin, could this be part of the next pretest, please?
Gavin Smith
2017-04-29 08:01:18 UTC
Permalink
Post by Eli Zaretskii
Date: Thu, 27 Apr 2017 19:03:35 +0200
Thanks for the report and suggested fix.
The #ifdefology here seems a bit fragile to me (will likely break in other
I only know of 2 flavors of MinGW (and wish there were only one), but
of course an Autoconf test is even better. Thanks.
Gavin, could this be part of the next pretest, please?
Yes, I will make sure the Gnulib files have been updated.
Eli Zaretskii
2017-04-30 14:31:53 UTC
Permalink
Date: Thu, 27 Apr 2017 20:50:25 +0300
Date: Thu, 27 Apr 2017 19:03:35 +0200
Thanks for the report and suggested fix.
The #ifdefology here seems a bit fragile to me (will likely break in other
I only know of 2 flavors of MinGW (and wish there were only one), but
of course an Autoconf test is even better. Thanks.
It turns out the same problem exists in Gnulib's wchar.h, so it needs
the same solution. Bruno, could you do that, please?

(The reason I didn't see that before is because Gnulib's wchar.h is
used in Texinfo only when compiling the XS extensions, which I didn't
succeed in originally.)

TIA
Bruno Haible
2017-05-01 10:45:08 UTC
Permalink
Post by Eli Zaretskii
It turns out the same problem exists in Gnulib's wchar.h, so it needs
the same solution. Bruno, could you do that, please?
Done per patch below.
Post by Eli Zaretskii
(The reason I didn't see that before is because Gnulib's wchar.h is
used in Texinfo only when compiling the XS extensions, which I didn't
succeed in originally.)
You don't need to apologize for not reporting all bugs together. We always
report and fix bugs one by one.


2017-05-01 Bruno Haible <***@clisp.org>

wchar: Fix compilation error with the original mingw.org mingw.
* lib/wchar.in.h (rpl_wint_t): If <crtdefs.h> does not exist, include
<stddef.h> instead.
* m4/wint_t.m4 (gl_TYPE_WINT_T_PREREQ): New macro, extracted from
gl_WCTYPE_H.
* m4/wctype_h.m4 (gl_WCTYPE_H): Don't set HAVE_CRTDEFS_H here; require
gl_TYPE_WINT_T_PREREQ instead.
* m4/wchar_h.m4 (gl_WCHAR_H): Require gl_TYPE_WINT_T_PREREQ.
* modules/wchar (Makefile.am): Substitute HAVE_CRTDEFS_H.
Reported by Eli Zaretskii <***@gnu.org>.

diff --git a/lib/wchar.in.h b/lib/wchar.in.h
index ef155d2..8666b5d 100644
--- a/lib/wchar.in.h
+++ b/lib/wchar.in.h
@@ -113,12 +113,16 @@
# define WEOF -1
# endif
#else
-/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h>.
- This is too small: ISO C 99 section 7.24.1.(2) says that wint_t must be
- "unchanged by default argument promotions". Override it. */
+/* mingw and MSVC define wint_t as 'unsigned short' in <crtdefs.h> or
+ <stddef.h>. This is too small: ISO C 99 section 7.24.1.(2) says that
+ wint_t must be "unchanged by default argument promotions". Override it. */
# if @GNULIB_OVERRIDES_WINT_T@
# if !GNULIB_defined_wint_t
-# include <crtdefs.h>
+# if @HAVE_CRTDEFS_H@
+# include <crtdefs.h>
+# else
+# include <stddef.h>
+# endif
typedef unsigned int rpl_wint_t;
# undef wint_t
# define wint_t rpl_wint_t
diff --git a/m4/wchar_h.m4 b/m4/wchar_h.m4
index 621cfb9..1a2734c 100644
--- a/m4/wchar_h.m4
+++ b/m4/wchar_h.m4
@@ -7,7 +7,7 @@ dnl with or without modifications, as long as this notice is preserved.

dnl Written by Eric Blake.

-# wchar_h.m4 serial 41
+# wchar_h.m4 serial 42

AC_DEFUN([gl_WCHAR_H],
[
@@ -35,6 +35,8 @@ AC_DEFUN([gl_WCHAR_H],
fi
AC_SUBST([HAVE_WINT_T])

+ AC_REQUIRE([gl_TYPE_WINT_T_PREREQ])
+
dnl Check for declarations of anything we want to poison if the
dnl corresponding gnulib module is not in use.
gl_WARN_ON_USE_PREPARE([[
diff --git a/m4/wctype_h.m4 b/m4/wctype_h.m4
index c72a73f..0c8c305 100644
--- a/m4/wctype_h.m4
+++ b/m4/wctype_h.m4
@@ -1,4 +1,4 @@
-# wctype_h.m4 serial 19
+# wctype_h.m4 serial 20

dnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it.

@@ -30,6 +30,8 @@ AC_DEFUN([gl_WCTYPE_H],
fi
AC_SUBST([HAVE_WINT_T])

+ AC_REQUIRE([gl_TYPE_WINT_T_PREREQ])
+
gl_CHECK_NEXT_HEADERS([wctype.h])
if test $ac_cv_header_wctype_h = yes; then
if test $ac_cv_func_iswcntrl = yes; then
@@ -66,14 +68,6 @@ AC_DEFUN([gl_WCTYPE_H],
fi
AC_SUBST([HAVE_WCTYPE_H])

- AC_CHECK_HEADERS_ONCE([crtdefs.h])
- if test $ac_cv_header_crtdefs_h = yes; then
- HAVE_CRTDEFS_H=1
- else
- HAVE_CRTDEFS_H=0
- fi
- AC_SUBST([HAVE_CRTDEFS_H])
-
case "$gl_cv_func_iswcntrl_works" in
*yes) REPLACE_ISWCNTRL=0 ;;
*) REPLACE_ISWCNTRL=1 ;;
diff --git a/m4/wint_t.m4 b/m4/wint_t.m4
index 65e25a4..d30b8bc 100644
--- a/m4/wint_t.m4
+++ b/m4/wint_t.m4
@@ -1,4 +1,4 @@
-# wint_t.m4 serial 6
+# wint_t.m4 serial 7
dnl Copyright (C) 2003, 2007-2017 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
@@ -60,3 +60,15 @@ AC_DEFUN([gt_TYPE_WINT_T],
fi
AC_SUBST([GNULIB_OVERRIDES_WINT_T])
])
+
+dnl Prerequisites of the 'wint_t' override.
+AC_DEFUN([gl_TYPE_WINT_T_PREREQ],
+[
+ AC_CHECK_HEADERS_ONCE([crtdefs.h])
+ if test $ac_cv_header_crtdefs_h = yes; then
+ HAVE_CRTDEFS_H=1
+ else
+ HAVE_CRTDEFS_H=0
+ fi
+ AC_SUBST([HAVE_CRTDEFS_H])
+])
diff --git a/modules/wchar b/modules/wchar
index 73012c6..31770d8 100644
--- a/modules/wchar
+++ b/modules/wchar
@@ -31,6 +31,7 @@ wchar.h: wchar.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H)
-e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \
-e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \
-e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \
+ -e 's/@''HAVE_CRTDEFS_H''@/$(HAVE_CRTDEFS_H)/g' \
-e 's/@''GNULIB_OVERRIDES_WINT_T''@/$(GNULIB_OVERRIDES_WINT_T)/g' \
-e 's/@''GNULIB_BTOWC''@/$(GNULIB_BTOWC)/g' \
-e 's/@''GNULIB_WCTOB''@/$(GNULIB_WCTOB)/g' \
Eli Zaretskii
2017-05-01 10:54:52 UTC
Permalink
Date: Mon, 01 May 2017 12:45:08 +0200
Post by Eli Zaretskii
It turns out the same problem exists in Gnulib's wchar.h, so it needs
the same solution. Bruno, could you do that, please?
Done per patch below.
Thanks.

Loading...