mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-08 18:24:04 +02:00
There are now C99 functions that the printf items want to use that may not be necessarily supported by the math.h that is shipped by the compiler, such as signbit(), isinf(), isnan() and isfinite() and their double, long and float counterparts. This checks for whether these functions are provided by the math.h shipped by the compiler, and builds the gnulib implementations of them if they cannot be found. Currently no attempt is made to check whether these, if available from the compiler's math.h, are compliant with the specs.
344 lines
8.4 KiB
Meson
344 lines
8.4 KiB
Meson
# glib enables -Werror=format-nonliteral by default, but the embedded gnulib
|
|
# needs to handle user provided format strings.
|
|
extra_gnulib_args = cc.get_supported_arguments([
|
|
'-Wno-format-nonliteral', '-Wno-duplicated-branches'])
|
|
|
|
math_h_config = configuration_data ()
|
|
|
|
unneeded_funcs = [
|
|
'ACOSF',
|
|
'ACOSL',
|
|
'ASINF',
|
|
'ASINL',
|
|
'ATAN2F',
|
|
'ATANF',
|
|
'ATANL',
|
|
'CBRT',
|
|
'CBRTF',
|
|
'CBRTL',
|
|
'CEIL',
|
|
'CEILF',
|
|
'CEILL',
|
|
'COPYSIGN',
|
|
'COPYSIGNF',
|
|
'COPYSIGNL',
|
|
'COSF',
|
|
'COSHF',
|
|
'COSL',
|
|
'EXP2',
|
|
'EXP2F',
|
|
'EXP2L',
|
|
'EXPF',
|
|
'EXPL',
|
|
'EXPM1',
|
|
'EXPM1F',
|
|
'EXPM1L',
|
|
'FABSF',
|
|
'FABSL',
|
|
'FLOOR',
|
|
'FLOORF',
|
|
'FLOORL',
|
|
'FMA',
|
|
'FMAF',
|
|
'FMAL',
|
|
'FMOD',
|
|
'FMODF',
|
|
'FMODL',
|
|
'FREXPF',
|
|
'HYPOT',
|
|
'HYPOTF',
|
|
'HYPOTL',
|
|
'ILOGB',
|
|
'ILOGBF',
|
|
'ILOGBL',
|
|
'LDEXPF',
|
|
'LOG',
|
|
'LOG10',
|
|
'LOG10F',
|
|
'LOG10L',
|
|
'LOG1P',
|
|
'LOG1PF',
|
|
'LOG1PL',
|
|
'LOG2',
|
|
'LOG2F',
|
|
'LOG2L',
|
|
'LOGB',
|
|
'LOGBF',
|
|
'LOGBL',
|
|
'LOGF',
|
|
'LOGL',
|
|
'MODF',
|
|
'MODFF',
|
|
'MODFL',
|
|
'POWF',
|
|
'REMAINDER',
|
|
'REMAINDERF',
|
|
'REMAINDERL',
|
|
'RINT',
|
|
'RINTF',
|
|
'RINTL',
|
|
'ROUND',
|
|
'ROUNDF',
|
|
'ROUNDL',
|
|
'SINF',
|
|
'SINHF',
|
|
'SINL',
|
|
'SQRTF',
|
|
'SQRTL',
|
|
'TANF',
|
|
'TANHF',
|
|
'TANL',
|
|
'TRUNC',
|
|
'TRUNCF',
|
|
'TRUNCL',
|
|
]
|
|
|
|
foreach f : unneeded_funcs
|
|
math_h_config.set ('GNULIB_' + f, 0)
|
|
# These are not used in practice, guarded by
|
|
# the appropriate GNULIB_*, but meson config
|
|
# processor doesn't know that
|
|
math_h_config.set ('HAVE_' + f, 'variable not used')
|
|
math_h_config.set ('REPLACE_' + f, 'variable not used')
|
|
endforeach
|
|
|
|
needed_funcs = [
|
|
'FREXP',
|
|
'FREXPL',
|
|
'ISFINITE',
|
|
'ISINF',
|
|
'ISNAN',
|
|
'ISNAND',
|
|
'ISNANF',
|
|
'ISNANL',
|
|
'LDEXPL',
|
|
'SIGNBIT',
|
|
]
|
|
|
|
foreach f : needed_funcs
|
|
math_h_config.set ('GNULIB_' + f, 1)
|
|
endforeach
|
|
|
|
math_h_config.set ('GUARD_PREFIX', 'GL')
|
|
|
|
decls_for_unused_funcs = [
|
|
'ACOSL',
|
|
'ASINL',
|
|
'ATANL',
|
|
'CBRTF',
|
|
'CBRTL',
|
|
'CEILF',
|
|
'CEILL',
|
|
'COPYSIGNF',
|
|
'COSL',
|
|
'EXP2',
|
|
'EXP2F',
|
|
'EXP2L',
|
|
'EXPL',
|
|
'EXPM1L',
|
|
'FLOORF',
|
|
'FLOORL',
|
|
'LOG10L',
|
|
'LOG2',
|
|
'LOG2F',
|
|
'LOG2L',
|
|
'LOGB',
|
|
'LOGL',
|
|
'REMAINDER',
|
|
'REMAINDERL',
|
|
'RINTF',
|
|
'ROUND',
|
|
'ROUNDF',
|
|
'ROUNDL',
|
|
'SINL',
|
|
'SQRTL',
|
|
'TANL',
|
|
'TRUNC',
|
|
'TRUNCF',
|
|
'TRUNCL',
|
|
]
|
|
|
|
foreach f : decls_for_unused_funcs
|
|
math_h_config.set ('HAVE_DECL_' + f, 0)
|
|
endforeach
|
|
|
|
decls_for_used_funcs = [
|
|
'frexpl',
|
|
'ldexpl',
|
|
]
|
|
|
|
foreach f : decls_for_used_funcs
|
|
compiles = cc.compiles('''#include <math.h>
|
|
int main ()
|
|
{
|
|
(void) @0@;
|
|
return 0;
|
|
}
|
|
'''.format (f))
|
|
math_h_config.set ('HAVE_DECL_' + f.to_upper (), compiles ? 1 : 0)
|
|
set_variable ('have_decl_' + f, compiles ? true : false)
|
|
endforeach
|
|
|
|
nan_tmpl = '''#include <math.h>
|
|
#if __GNUC__ >= 4
|
|
# undef @0@
|
|
# define @0@(x) __builtin_isnan ((@1@)(x))
|
|
#else
|
|
# undef @0@
|
|
# define @0@(x) isnan ((@1@)(x))
|
|
#endif
|
|
double x;
|
|
int main () {return @0@ (x);}
|
|
'''
|
|
|
|
links = cc.links (nan_tmpl.format ('isnand', 'double'),
|
|
dependencies : [libm])
|
|
math_h_config.set ('HAVE_ISNAND', links ? 1 : 0)
|
|
math_h_config.set ('HAVE_ISNAND_IN_LIBC', links ? 1 : 0)
|
|
set_variable ('have_isnand', links)
|
|
|
|
links = cc.links (nan_tmpl.format ('isnanl', 'long double'),
|
|
dependencies : [libm])
|
|
math_h_config.set ('HAVE_ISNANL', links ? 1 : 0)
|
|
math_h_config.set ('HAVE_ISNANL_IN_LIBC', links ? 1 : 0)
|
|
set_variable ('have_isnanl', links)
|
|
|
|
links = cc.links ('''#include <math.h>
|
|
double x;
|
|
int y;
|
|
int main () {return ldexp (x, y) < 1;}
|
|
''',
|
|
dependencies : [libm])
|
|
math_h_config.set ('HAVE_LDEXP', links ? 1 : 0)
|
|
math_h_config.set ('HAVE_LDEXP_IN_LIBC', links ? 1 : 0)
|
|
set_variable ('have_ldexp', links)
|
|
|
|
links = cc.links ('''#include <math.h>
|
|
long double x;
|
|
int main () {return ldexpl (x, -1) > 0;}
|
|
''',
|
|
dependencies : [libm])
|
|
math_h_config.set ('HAVE_LDEXPL', links ? 1 : 0)
|
|
math_h_config.set ('HAVE_LDEXPL_IN_LIBC', links ? 1 : 0)
|
|
set_variable ('have_ldexpl', links)
|
|
|
|
links = cc.links ('''#include <math.h>
|
|
double x;
|
|
int main () {int e; return frexp (x, &e) > 0;}
|
|
''',
|
|
dependencies : [libm])
|
|
math_h_config.set ('HAVE_FREXP', links ? 1 : 0)
|
|
math_h_config.set ('HAVE_FREXP_IN_LIBC', links ? 1 : 0)
|
|
set_variable ('have_frexp', links)
|
|
|
|
links = cc.links ('''#include <math.h>
|
|
long double x;
|
|
int main () {int e; return frexpl (x, &e) > 0;}
|
|
''',
|
|
dependencies : [libm])
|
|
math_h_config.set ('HAVE_FREXPL', links ? 1 : 0)
|
|
math_h_config.set ('HAVE_FREXPL_IN_LIBC', links ? 1 : 0)
|
|
set_variable ('have_frexpl', links)
|
|
|
|
math_h_config.set ('INCLUDE_NEXT_AS_FIRST_DIRECTIVE', 'include')
|
|
math_h_config.set ('NEXT_AS_FIRST_DIRECTIVE_MATH_H', '<math.h>')
|
|
math_h_config.set ('PRAGMA_COLUMNS', '')
|
|
math_h_config.set ('PRAGMA_SYSTEM_HEADER', '')
|
|
|
|
compiles = cc.compiles ('''
|
|
#include <math.h>
|
|
/* Solaris 10 has a broken definition of NAN. Other platforms
|
|
fail to provide NAN, or provide it only in C99 mode; this
|
|
test only needs to fail when NAN is provided but wrong. */
|
|
int main () {
|
|
float f = 1.0f;
|
|
#ifdef NAN
|
|
f = NAN;
|
|
#endif
|
|
return f == 0;
|
|
}
|
|
''')
|
|
math_h_config.set ('REPLACE_NAN', compiles ? 0 : 1)
|
|
|
|
if have_frexp
|
|
subdir ('gl_cv_func_frexp_works')
|
|
else
|
|
gl_cv_func_frexp_works = false
|
|
gl_cv_func_frexp_broken_beyond_repair = true
|
|
endif
|
|
if have_frexpl
|
|
subdir ('gl_cv_func_frexpl_works')
|
|
else
|
|
gl_cv_func_frexpl_works = false
|
|
gl_cv_func_frexpl_broken_beyond_repair = true
|
|
endif
|
|
|
|
if not gl_cv_func_frexp_works and gl_cv_func_frexp_broken_beyond_repair
|
|
error ('frexp() is missing or broken beyond repair, and we have nothing to replace it with')
|
|
endif
|
|
if not gl_cv_func_frexpl_works and gl_cv_func_frexpl_broken_beyond_repair
|
|
error ('frexpl() is missing or broken beyond repair, and we have nothing to replace it with')
|
|
endif
|
|
|
|
math_h_config.set ('REPLACE_FREXP', gl_cv_func_frexp_works ? 0 : 1)
|
|
math_h_config.set ('REPLACE_FREXPL', gl_cv_func_frexpl_works ? 0 : 1)
|
|
math_h_config.set ('HAVE_DECL_FREXPL', gl_cv_func_frexpl_decl ? 0 : 1)
|
|
|
|
math_h_config.set ('REPLACE_ITOLD', 0)
|
|
math_h_config.set ('REPLACE_HUGE_VAL', 0)
|
|
math_h_config.set ('REPLACE_SIGNBIT_USING_GCC', 0)
|
|
|
|
if have_ldexpl
|
|
subdir ('gl_cv_func_ldexpl_works')
|
|
else
|
|
gl_cv_func_ldexpl_works = false
|
|
endif
|
|
math_h_config.set ('REPLACE_LDEXPL', gl_cv_func_ldexpl_works ? 0 : 1)
|
|
math_h_config.set ('HAVE_DECL_LDEXPL', gl_cv_func_ldexpl_decl ? 0 : 1)
|
|
|
|
inf_tmpl = '''#include <math.h>
|
|
double x;
|
|
int main () {return @0@ (x);}
|
|
'''
|
|
|
|
other_needed_math_sources = []
|
|
# Some compilers may not have isfinite, isinf available
|
|
foreach f: ['isfinite', 'isinf', 'isnan', 'isnanf', 'signbit']
|
|
links = cc.links (inf_tmpl.format('@0@'.format(f)),
|
|
dependencies : [libm])
|
|
math_h_config.set ('HAVE_@0@'.format(f.to_upper()), links ? 1 : 0)
|
|
math_h_config.set ('HAVE_@0@_IN_LIBC'.format(f.to_upper()), links ? 1 : 0)
|
|
math_h_config.set ('REPLACE_@0@'.format(f.to_upper()), links ? 0 : 1)
|
|
set_variable ('have_@0@'.format(f), links)
|
|
if not links
|
|
if f == 'signbit'
|
|
other_needed_math_sources += [ 'signbitd.c', 'signbitf.c', 'signbitl.c' ]
|
|
elif f != 'isfinite' and f != 'isnan'
|
|
other_needed_math_sources += [ '@0@.c'.format(f) ]
|
|
endif
|
|
endif
|
|
endforeach
|
|
|
|
math_h = configure_file (input: 'gnulib_math.h.in',
|
|
output: 'gnulib_math.h',
|
|
configuration: math_h_config)
|
|
|
|
gnulib_sources = ['asnprintf.c', 'printf.c', 'printf-args.c', 'printf-parse.c', 'printf-frexp.c', 'printf-frexpl.c', 'isnand.c', 'isnanl.c', 'vasnprintf.c']
|
|
|
|
if not gl_cv_func_frexp_works
|
|
gnulib_sources += ['frexp.c']
|
|
endif
|
|
if not gl_cv_func_frexpl_works
|
|
gnulib_sources += ['frexpl.c']
|
|
endif
|
|
|
|
gnulib_sources += other_needed_math_sources
|
|
|
|
gnulib_lib = static_library('gnulib', gnulib_sources,
|
|
dependencies : [libm],
|
|
include_directories : [configinc, glibinc, include_directories ('.')],
|
|
pic : true,
|
|
c_args : ['-DGCC_LINT=1', '-DLIBDIR="@0@"'.format(get_option('libdir')), '-DGLIB_COMPILATION', '-DG_LOG_DOMAIN="GLib"' ] + glib_hidden_visibility_args + extra_gnulib_args)
|
|
|
|
gnulib_libm_dependency = [libm]
|