From d5fec6c22f03c6a73d62260c9ce091c10c0a9cbd Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Wed, 22 Jan 2014 20:39:45 -0700 Subject: [PATCH] pthread: work around winpthread header pollution on mingw Dan Berrange reported compilation failure of libvirt on Fedora 20 when cross-compiling to mingw; the problem was traced to bogus macros in the winpthreads header shipped as part of mingw-headers 3.0. CC util/libvirt_util_la-virerror.lo In file included from /usr/i686-w64-mingw32/sys-root/mingw/include/sys/time.h:10:0, from ../gnulib/lib/sys/time.h:39, from ../gnulib/lib/sys/select.h:117, from util/virutil.h:31, from util/virerror.c:35: ../gnulib/lib/time.h:468:21: error: expected identifier or '(' before '{' token _GL_FUNCDECL_SYS (localtime_r, struct tm *, (time_t const *restrict __timer, ^ Gnulib's time.h was already working around the pthread.h pollution, but now that newer mingw has started providing struct timespec, the workaround was no longer being hit. Moving the pollution workaround to the wrapper around the broken header solves the problem. * lib/time.in.h: Move pthread workarounds... * lib/pthread.in.h: ...here. * m4/pthread.m4 (gl_PTHREAD_CHECK): Also build pthread.h when we detect macro pollution on mingw. * doc/posix-headers/pthread.texi (pthread.h): Document the problems. Signed-off-by: Eric Blake --- ChangeLog | 9 +++++++++ doc/posix-headers/pthread.texi | 13 ++++++++++--- lib/pthread.in.h | 9 +++++++++ lib/time.in.h | 11 ++--------- m4/pthread.m4 | 17 ++++++++++++++++- 5 files changed, 46 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index b7c3e0fc2..d117e7585 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2014-01-23 Eric Blake + + pthread: work around winpthread header pollution on mingw + * lib/time.in.h: Move pthread workarounds... + * lib/pthread.in.h: ...here. + * m4/pthread.m4 (gl_PTHREAD_CHECK): Also build pthread.h when we + detect macro pollution on mingw. + * doc/posix-headers/pthread.texi (pthread.h): Document the problems. + 2014-01-22 Paul Eggert qacl: check for fchmod diff --git a/doc/posix-headers/pthread.texi b/doc/posix-headers/pthread.texi index 5fb1d2e5d..cb4d2b80a 100644 --- a/doc/posix-headers/pthread.texi +++ b/doc/posix-headers/pthread.texi @@ -3,15 +3,22 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html} -Gnulib module: --- +Gnulib module: pthread Portability problems fixed by Gnulib: @itemize +@item +This header pollutes the namespace with some broken macro +implementations for various functions such as @code{strtok_r} and +@code{gmtime_r}: +mingw 3.0. @end itemize Portability problems not fixed by Gnulib: @itemize @item -This header file is missing on some platforms: -Minix 3.1.8, mingw, MSVC 9, BeOS. +This header file is missing on some platforms; the replacement does +not offer threads, so much as lightweight stubs that make conditional +compilation easier for fallbacks to single-threaded programs. +Minix 3.1.8, mingw 2.x, MSVC 9, BeOS. @end itemize diff --git a/lib/pthread.in.h b/lib/pthread.in.h index a8438df9b..764b34688 100644 --- a/lib/pthread.in.h +++ b/lib/pthread.in.h @@ -36,6 +36,15 @@ #include #undef __need_system_stdlib_h + +/* The pthreads-win32 defines a couple of broken macros. */ +#undef asctime_r +#undef ctime_r +#undef gmtime_r +#undef localtime_r +#undef rand_r +#undef strtok_r + #include #include #include diff --git a/lib/time.in.h b/lib/time.in.h index 10561397c..98ca30d46 100644 --- a/lib/time.in.h +++ b/lib/time.in.h @@ -48,20 +48,13 @@ /* Some systems don't define struct timespec (e.g., AIX 4.1, Ultrix 4.3). Or they define it with the wrong member names or define it in - (e.g., FreeBSD circa 1997). Stock Mingw does not define it, but the - pthreads-win32 library defines it in . */ + (e.g., FreeBSD circa 1997). Stock Mingw prior to 3.0 does not define it, + but the pthreads-win32 library defines it in . */ # if ! @TIME_H_DEFINES_STRUCT_TIMESPEC@ # if @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ # include # elif @PTHREAD_H_DEFINES_STRUCT_TIMESPEC@ # include -/* The pthreads-win32 also defines a couple of broken macros. */ -# undef asctime_r -# undef ctime_r -# undef gmtime_r -# undef localtime_r -# undef rand_r -# undef strtok_r # else # ifdef __cplusplus diff --git a/m4/pthread.m4 b/m4/pthread.m4 index 2141e53f1..1ed0dd335 100644 --- a/m4/pthread.m4 +++ b/m4/pthread.m4 @@ -1,4 +1,4 @@ -# pthread.m4 serial 7 +# pthread.m4 serial 8 dnl Copyright (C) 2009-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -10,6 +10,19 @@ AC_DEFUN([gl_PTHREAD_CHECK], gl_CHECK_NEXT_HEADERS([pthread.h]) if test $ac_cv_header_pthread_h = yes; then HAVE_PTHREAD_H=1 + # mingw 3.0 uses winpthreads which installs broken macros via + AC_CACHE_CHECK([whether pollutes the namespace], + [gl_cv_header_pthread_h_pollution], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + #ifdef strtok_r + #error + break me + #endif + ]])], + [gl_cv_header_pthread_h_pollution=no], + [gl_cv_header_pthread_h_pollution=yes])]) else HAVE_PTHREAD_H=0 fi @@ -31,6 +44,8 @@ AC_DEFUN([gl_PTHREAD_CHECK], test $ac_cv_type_pthread_spinlock_t != yes; then PTHREAD_H='pthread.h' AC_LIBOBJ([pthread]) + elif test $gl_cv_header_pthread_h_pollution = yes; then + PTHREAD_H=pthread.h else PTHREAD_H= fi -- 2.11.0