| 1 | # mathfunc.m4 serial 11 |
| 2 | dnl Copyright (C) 2010-2014 Free Software Foundation, Inc. |
| 3 | dnl This file is free software; the Free Software Foundation |
| 4 | dnl gives unlimited permission to copy and/or distribute it, |
| 5 | dnl with or without modifications, as long as this notice is preserved. |
| 6 | |
| 7 | # gl_MATHFUNC(FUNC, RETTYPE, PARAMTYPES [, INCLUDES] [, EXTRA-CODE]) |
| 8 | # ------------------------------------------------------------------ |
| 9 | # tests whether the function FUNC is available in libc or libm. |
| 10 | # RETTYPE is the return type. PARAMTYPES is a parameter list, with parentheses. |
| 11 | # It sets FUNC_LIBM to empty or "-lm" accordingly. |
| 12 | |
| 13 | AC_DEFUN([gl_MATHFUNC], |
| 14 | [ |
| 15 | dnl We need the RETTYPE and PARAMTYPES in order to force linking with the |
| 16 | dnl function. |
| 17 | dnl 1) With gcc >= 4.3 on glibc/x86_64, calls to the 'fabs' function |
| 18 | dnl are inlined by the compiler, therefore linking of these calls does |
| 19 | dnl not require -lm, but taking the function pointer of 'fabs' does. |
| 20 | dnl 2) On MSVC 9, many math functions exist only as macros with arguments, |
| 21 | dnl whereas the function pointer is undefined. |
| 22 | dnl On the other hand, taking just the function pointer is not enough. |
| 23 | dnl 1) On AIX 7.1, when 'long double' is 128 bit large ("xlc -qldbl128" or |
| 24 | dnl "xlc -qlongdouble" or "gcc -mlong-double-128") many math functions |
| 25 | dnl exist as macros with arguments, that may reference libm or even |
| 26 | dnl completely undefined functions such as __rint128. |
| 27 | dnl 2) In AIX 7.1 with gcc 4.2, when optimization is turned on, calls to |
| 28 | dnl rint() with simple arguments are turned into rintf() calls by the |
| 29 | dnl compiler. But while rint() is resides in libc, rintf() is in libm. |
| 30 | m4_pushdef([func], [$1]) |
| 31 | m4_pushdef([FUNC], [m4_translit([$1],[abcdefghijklmnopqrstuvwxyz], |
| 32 | [ABCDEFGHIJKLMNOPQRSTUVWXYZ])]) |
| 33 | m4_pushdef([ARGS], [m4_bpatsubst( |
| 34 | [m4_bpatsubst( |
| 35 | [m4_bpatsubst( |
| 36 | [m4_bpatsubst( |
| 37 | [m4_bpatsubst( |
| 38 | [m4_bpatsubst( |
| 39 | [m4_bpatsubst( |
| 40 | [m4_bpatsubst( |
| 41 | [m4_bpatsubst( |
| 42 | [$3], |
| 43 | [int \*], [&i_ret])], |
| 44 | [float \*], [&f_ret])], |
| 45 | [double \*], [&d_ret])], |
| 46 | [long double \*], [&l_ret])], |
| 47 | [int], [2])], |
| 48 | [float], [1.618034f])], |
| 49 | [long double], [1.618033988749894848L])], |
| 50 | [double], [1.6180339887])], |
| 51 | [void], [])]) |
| 52 | FUNC[]_LIBM= |
| 53 | AC_CACHE_CHECK([whether func() can be used without linking with libm], |
| 54 | [gl_cv_func_]func[_no_libm], |
| 55 | [ |
| 56 | AC_LINK_IFELSE( |
| 57 | [AC_LANG_PROGRAM( |
| 58 | [[#ifndef __NO_MATH_INLINES |
| 59 | # define __NO_MATH_INLINES 1 /* for glibc */ |
| 60 | #endif |
| 61 | #include <math.h> |
| 62 | $4 |
| 63 | $2 (*funcptr) $3 = ]func[; |
| 64 | int i_ret; |
| 65 | float f_ret; |
| 66 | double d_ret; |
| 67 | long double l_ret;]], |
| 68 | [[$2 y = funcptr ]ARGS[ + ]func[ ]ARGS[; |
| 69 | $5 |
| 70 | return y < 0.3 || y > 1.7; |
| 71 | ]])], |
| 72 | [gl_cv_func_]func[_no_libm=yes], |
| 73 | [gl_cv_func_]func[_no_libm=no]) |
| 74 | ]) |
| 75 | if test $gl_cv_func_[]func[]_no_libm = no; then |
| 76 | AC_CACHE_CHECK([whether func() can be used with libm], |
| 77 | [gl_cv_func_]func[_in_libm], |
| 78 | [ |
| 79 | save_LIBS="$LIBS" |
| 80 | LIBS="$LIBS -lm" |
| 81 | AC_LINK_IFELSE( |
| 82 | [AC_LANG_PROGRAM( |
| 83 | [[#ifndef __NO_MATH_INLINES |
| 84 | # define __NO_MATH_INLINES 1 /* for glibc */ |
| 85 | #endif |
| 86 | #include <math.h> |
| 87 | $4 |
| 88 | $2 (*funcptr) $3 = ]func[; |
| 89 | int i_ret; |
| 90 | float f_ret; |
| 91 | double d_ret; |
| 92 | long double l_ret;]], |
| 93 | [[$2 y = funcptr ]ARGS[ + ]func[ ]ARGS[; |
| 94 | $5 |
| 95 | return y < 0.3 || y > 1.7; |
| 96 | ]])], |
| 97 | [gl_cv_func_]func[_in_libm=yes], |
| 98 | [gl_cv_func_]func[_in_libm=no]) |
| 99 | LIBS="$save_LIBS" |
| 100 | ]) |
| 101 | if test $gl_cv_func_[]func[]_in_libm = yes; then |
| 102 | FUNC[]_LIBM=-lm |
| 103 | fi |
| 104 | fi |
| 105 | AC_SUBST(FUNC[_LIBM]) |
| 106 | m4_popdef([ARGS]) |
| 107 | m4_popdef([FUNC]) |
| 108 | m4_popdef([func]) |
| 109 | ]) |
| 110 | |
| 111 | # gl_COMMON_DOUBLE_MATHFUNC(FUNC) |
| 112 | # ------------------------------- |
| 113 | # tests whether the function FUNC is available in libc or libm. |
| 114 | # It sets FUNC_LIBM to empty or "-lm" accordingly. |
| 115 | # FUNC must be one of the following functions, that are present on all systems |
| 116 | # and provided by libm on all systems except Mac OS X, BeOS, Haiku: |
| 117 | # acos asin atan atan2 cbrt cos cosh erf erfc exp fmod hypot j0 j1 jn lgamma |
| 118 | # log log10 log1p pow remainder sin sinh sqrt tan tanh y0 y1 yn |
| 119 | |
| 120 | AC_DEFUN([gl_COMMON_DOUBLE_MATHFUNC], |
| 121 | [ |
| 122 | AC_REQUIRE([gl_COMMON_DOUBLE_MATHFUNC_TEST]) |
| 123 | m4_pushdef([FUNC], [m4_translit([$1],[abcdefghijklmnopqrstuvwxyz], |
| 124 | [ABCDEFGHIJKLMNOPQRSTUVWXYZ])]) |
| 125 | FUNC[]_LIBM="$POW_LIBM" |
| 126 | AC_SUBST(FUNC[_LIBM]) |
| 127 | m4_popdef([FUNC]) |
| 128 | ]) |
| 129 | |
| 130 | AC_DEFUN([gl_COMMON_DOUBLE_MATHFUNC_TEST], |
| 131 | [ |
| 132 | dnl We could use any of the following: |
| 133 | dnl gl_MATHFUNC([acos], [double], [(double)]) |
| 134 | dnl gl_MATHFUNC([asin], [double], [(double)]) |
| 135 | dnl gl_MATHFUNC([atan], [double], [(double)]) |
| 136 | dnl gl_MATHFUNC([atan2], [double], [(double, double)]) |
| 137 | dnl gl_MATHFUNC([cbrt], [double], [(double)]) |
| 138 | dnl gl_MATHFUNC([cos], [double], [(double)]) |
| 139 | dnl gl_MATHFUNC([cosh], [double], [(double)]) |
| 140 | dnl gl_MATHFUNC([erf], [double], [(double)]) |
| 141 | dnl gl_MATHFUNC([erfc], [double], [(double)]) |
| 142 | dnl gl_MATHFUNC([exp], [double], [(double)]) |
| 143 | dnl gl_MATHFUNC([fmod], [double], [(double, double)]) |
| 144 | dnl gl_MATHFUNC([hypot], [double], [(double, double)]) |
| 145 | dnl gl_MATHFUNC([j0], [double], [(double)]) |
| 146 | dnl gl_MATHFUNC([j1], [double], [(double)]) |
| 147 | dnl gl_MATHFUNC([jn], [double], [(int, double)]) |
| 148 | dnl gl_MATHFUNC([lgamma], [double], [(double)]) |
| 149 | dnl gl_MATHFUNC([log], [double], [(double)]) |
| 150 | dnl gl_MATHFUNC([log10], [double], [(double)]) |
| 151 | dnl gl_MATHFUNC([log1p], [double], [(double)]) |
| 152 | dnl gl_MATHFUNC([pow], [double], [(double, double)]) |
| 153 | dnl gl_MATHFUNC([remainder], [double], [(double, double)]) |
| 154 | dnl gl_MATHFUNC([sin], [double], [(double)]) |
| 155 | dnl gl_MATHFUNC([sinh], [double], [(double)]) |
| 156 | dnl gl_MATHFUNC([sqrt], [double], [(double)]) |
| 157 | dnl gl_MATHFUNC([tan], [double], [(double)]) |
| 158 | dnl gl_MATHFUNC([tanh], [double], [(double)]) |
| 159 | dnl gl_MATHFUNC([y0], [double], [(double)]) |
| 160 | dnl gl_MATHFUNC([y1], [double], [(double)]) |
| 161 | dnl gl_MATHFUNC([yn], [double], [(int, double)]) |
| 162 | gl_MATHFUNC([pow], [double], [(double, double)]) |
| 163 | ]) |