The gnulib CI failed today, with this error: depbase=`echo c-vsnprintf.o | sed 's|[^/]*$|.deps/&|;s|\.o$||'`;\ ccache gcc -DHAVE_CONFIG_H -DEXEEXT=\"\" -DEXEEXT=\"\" -DNO_XMALLOC -DEXEEXT=\"\" -I. -I.. -DGNULIB_STRICT_CHECKING=1 -fvisibility=hidden -g -O2 -MT c-vsnprintf.o -MD -MP -MF $depbase.Tpo -c -o c-vsnprintf.o c-vsnprintf.c &&\ mv -f $depbase.Tpo $depbase.Po In file included from /usr/include/x86_64-linux-gnu/sys/types.h:196, from ./sys/types.h:46, from ./stdio.h:76, from c-vasnprintf.h:32, from c-vasnprintf.c:20: ./math.h:3288:1: error: conflicting types for 'totalorderf' _GL_FUNCDECL_SYS (totalorderf, int, (float const *, float const *)); ^~~~~~~~~~~~~~~~ In file included from ./math.h:46, from vasnprintf.c:107, from c-vasnprintf.c:46: /usr/include/x86_64-linux-gnu/bits/mathcalls.h:371:1: note: previous declaration of 'totalorderf' was here __MATHDECL_1 (int, totalorder,, (_Mdouble_ __x, _Mdouble_ __y)) ^~~~~~~~~~~~ In file included from /usr/include/x86_64-linux-gnu/sys/types.h:196, from ./sys/types.h:46, from ./stdio.h:76, from c-vasnprintf.h:32, from c-vasnprintf.c:20: ./math.h:3311:1: error: conflicting types for 'totalorder' _GL_FUNCDECL_SYS (totalorder, int, (double const *, double const *)); ^~~~~~~~~~~~~~~~ In file included from /usr/include/features.h:424, from /usr/include/assert.h:35, from ./assert.h:26, from ../config.h:8358, from c-vasnprintf.c:17: /usr/include/x86_64-linux-gnu/bits/mathcalls.h:371:1: note: previous declaration of 'totalorder' was here __MATHDECL_1 (int, totalorder,, (_Mdouble_ __x, _Mdouble_ __y)) ^~~~~~~~~~~~ In file included from /usr/include/x86_64-linux-gnu/sys/types.h:196, from ./sys/types.h:46, from ./stdio.h:76, from c-vasnprintf.h:32, from c-vasnprintf.c:20: ./math.h:3338:1: error: conflicting types for 'totalorderl' _GL_FUNCDECL_SYS (totalorderl, int, ^~~~~~~~~~~~~~~~ In file included from ./math.h:46, from vasnprintf.c:107, from c-vasnprintf.c:46: /usr/include/x86_64-linux-gnu/bits/mathcalls.h:371:1: note: previous declaration of 'totalorderl' was here __MATHDECL_1 (int, totalorder,, (_Mdouble_ __x, _Mdouble_ __y)) ^~~~~~~~~~~~ make[4]: *** [Makefile:11173: c-vasnprintf.o] Error 1
Our documentation says "This function has a different signature on some platforms: glibc 2.30." The gnulib CI happens to be running on a Debian 10 system, that is, with glibc 2.28. And indeed, I reproduce the compilation error on Debian 10 and CentOS 8; both have glibc 2.28. The cause is the configuration code in m4/totalorder.m4. It attempts to decide based on the *_no_libm and *_in_libm variables whether to set REPLACE_TOTALORDER=1 or not. But that is not possible; it requires a test of the declaration in <math.h>, not a link test, to determine this. This patch fixes it. 2023-10-07 Bruno Haible <br...@clisp.org> totalorder*: Fix compilation error on glibc 2.25..2.30. * m4/totalorder.m4 (gl_FUNC_TOTALORDERF): Test whether <math.h> has an incompatible declaration of totalorderf, and set REPLACE_TOTALORDERF to 1 if so. (gl_FUNC_TOTALORDER): Test whether <math.h> has an incompatible declaration of totalorder, and set REPLACE_TOTALORDER to 1 if so. (gl_FUNC_TOTALORDERL): Test whether <math.h> has an incompatible declaration of totalorderl, and set REPLACE_TOTALORDERL to 1 if so. diff --git a/m4/totalorder.m4 b/m4/totalorder.m4 index 02c01fcd1a..ce264f4c65 100644 --- a/m4/totalorder.m4 +++ b/m4/totalorder.m4 @@ -9,22 +9,36 @@ AC_DEFUN([gl_FUNC_TOTALORDERF] AC_REQUIRE([gl_MATH_H_DEFAULTS]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - gl_MATHFUNC([totalorderf], [int], - [(float const *, float const *)], - [extern - #ifdef __cplusplus - "C" - #endif - int totalorderf (float const *, float const *); + dnl glibc versions < 2.31 had an incompatible declaration of this function, + dnl see <https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=42760d764649ad82f5fe45a26cbdf2c2500409f7> + AC_CACHE_CHECK([whether totalorderf has a non-standard declaration], + [gl_cv_func_totalorderf_incompatible], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include <math.h> + ]], + [[extern + #ifdef __cplusplus + "C" + #endif + int totalorderf (float const *, float const *); + ]]) + ], + [gl_cv_func_totalorderf_incompatible=no], + [gl_cv_func_totalorderf_incompatible=yes]) ]) - AS_IF([test $gl_cv_func_totalorderf_no_libm != yes && - test $gl_cv_func_totalorderf_in_libm != yes], - [if test $gl_cv_func_totalorderf_in_libm != yes; then - HAVE_TOTALORDERF=0 - else - REPLACE_TOTALORDERF=1 - fi - TOTALORDERF_LIBM='$(ISNANF_LIBM)']) + if test $gl_cv_func_totalorderf_incompatible = yes; then + REPLACE_TOTALORDERF=1 + else + gl_MATHFUNC([totalorderf], [int], [(float const *, float const *)]) + if test $gl_cv_func_totalorderf_no_libm != yes \ + && test $gl_cv_func_totalorderf_in_libm != yes; then + HAVE_TOTALORDERF=0 + fi + fi + if test $HAVE_TOTALORDERF = 0 || test $REPLACE_TOTALORDERF = 1; then + TOTALORDERF_LIBM='$(ISNANF_LIBM)' + fi AC_SUBST([TOTALORDERF_LIBM]) ]) @@ -33,22 +47,36 @@ AC_DEFUN([gl_FUNC_TOTALORDER] AC_REQUIRE([gl_MATH_H_DEFAULTS]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - gl_MATHFUNC([totalorder], [int], - [(double const *, double const *)], - [extern - #ifdef __cplusplus - "C" - #endif - int totalorder (double const *, double const *); + dnl glibc versions < 2.31 had an incompatible declaration of this function, + dnl see <https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=42760d764649ad82f5fe45a26cbdf2c2500409f7> + AC_CACHE_CHECK([whether totalorder has a non-standard declaration], + [gl_cv_func_totalorder_incompatible], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include <math.h> + ]], + [[extern + #ifdef __cplusplus + "C" + #endif + int totalorder (double const *, double const *); + ]]) + ], + [gl_cv_func_totalorder_incompatible=no], + [gl_cv_func_totalorder_incompatible=yes]) ]) - AS_IF([test $gl_cv_func_totalorder_no_libm != yes && - test $gl_cv_func_totalorder_in_libm != yes], - [if test $gl_cv_func_totalorder_in_libm != yes; then - HAVE_TOTALORDER=0 - else - REPLACE_TOTALORDER=1 - fi - TOTALORDER_LIBM='$(ISNAND_LIBM)']) + if test $gl_cv_func_totalorder_incompatible = yes; then + REPLACE_TOTALORDER=1 + else + gl_MATHFUNC([totalorder], [int], [(double const *, double const *)]) + if test $gl_cv_func_totalorder_no_libm != yes \ + && test $gl_cv_func_totalorder_in_libm != yes; then + HAVE_TOTALORDER=0 + fi + fi + if test $HAVE_TOTALORDER = 0 || test $REPLACE_TOTALORDER = 1; then + TOTALORDER_LIBM='$(ISNAND_LIBM)' + fi AC_SUBST([TOTALORDER_LIBM]) ]) @@ -57,24 +85,38 @@ AC_DEFUN([gl_FUNC_TOTALORDERL] AC_REQUIRE([gl_MATH_H_DEFAULTS]) AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) - gl_MATHFUNC([totalorderl], [int], - [(long double const *, long double const *)], - [extern - #ifdef __cplusplus - "C" - #endif - int totalorderl (long double const *, long double const *); - ]) - AS_IF([test $gl_cv_func_totalorderl_no_libm != yes && - test $gl_cv_func_totalorderl_in_libm != yes], - [if test $gl_cv_func_totalorderl_in_libm != yes; then - HAVE_TOTALORDERL=0 - else - REPLACE_TOTALORDERL=1 - fi - TOTALORDERL_LIBM='$(ISNANL_LIBM)' - dnl Prerequisite of lib/totalorderl.c. - gl_LONG_DOUBLE_SIGN_LOCATION + dnl glibc versions < 2.31 had an incompatible declaration of this function, + dnl see <https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=42760d764649ad82f5fe45a26cbdf2c2500409f7> + AC_CACHE_CHECK([whether totalorderl has a non-standard declaration], + [gl_cv_func_totalorderl_incompatible], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include <math.h> + ]], + [[extern + #ifdef __cplusplus + "C" + #endif + int totalorderl (long double const *, long double const *); + ]]) + ], + [gl_cv_func_totalorderl_incompatible=no], + [gl_cv_func_totalorderl_incompatible=yes]) ]) + if test $gl_cv_func_totalorderl_incompatible = yes; then + REPLACE_TOTALORDERL=1 + else + gl_MATHFUNC([totalorderl], [int], + [(long double const *, long double const *)]) + if test $gl_cv_func_totalorderl_no_libm != yes \ + && test $gl_cv_func_totalorderl_in_libm != yes; then + HAVE_TOTALORDERL=0 + fi + fi + if test $HAVE_TOTALORDERL = 0 || test $REPLACE_TOTALORDERL = 1; then + TOTALORDERL_LIBM='$(ISNANL_LIBM)' + dnl Prerequisite of lib/totalorderl.c. + gl_LONG_DOUBLE_SIGN_LOCATION + fi AC_SUBST([TOTALORDERL_LIBM]) ])