Meson: Check for HAVE_GOOD_PRINTF

The HAVE_GOOD_PRINTF config variable determines whether we are able to
use the CRT-supplied *printf() functions directly, by determining whether
the CRT-supplied vsnprintf() and snprintf() functions support C99 well
enough.

This means, we need to build the gnulib subdir as a static lib in GLib, and use
the gnulib *printf() functions when:

-We are on Windows
-The CRT's vsnprintf() and snprintf() is not sufficiently C99-compliant.

This will fix the problem when the *printf() functions cause a CRT
abort() call on pre-2015 Visual Studio builds at least, and ensures that
the Visual Studio 2015+ builds will pass the printf tests in GLib, since
the *printf() in Visual Studio 2015/2017's CRT does not support the %n
format specifier, nor the positional parameters (which requires
different _*printf_p*() functions), as indicated by
glib/tests/test-printf.c.

https://bugzilla.gnome.org/show_bug.cgi?id=783270
This commit is contained in:
Chun-wei Fan 2017-07-17 15:51:54 +08:00
parent 79b84ba3fc
commit 72528938b7
3 changed files with 28 additions and 7 deletions

4
glib/gnulib/meson.build Normal file
View File

@ -0,0 +1,4 @@
gnulib_lib = static_library('gnulib', 'asnprintf.c', 'printf.c', 'printf-args.c', 'printf-parse.c', 'vasnprintf.c',
include_directories : configinc,
pic : true,
c_args : [ '-DLIBDIR="@0@"'.format(get_option('libdir')), '-DGLIB_COMPILATION', '-DG_LOG_DOMAIN="GLib"' ] + glib_hidden_visibility_args)

View File

@ -7,6 +7,11 @@ subdir('libcharset')
if not use_system_pcre
subdir('pcre')
endif
if have_good_vsnprintf and have_good_snprintf
gnulib_lib = []
else
subdir('gnulib')
endif
glib_headers = [
'glib.h',
@ -217,7 +222,7 @@ libglib = shared_library('glib-2.0',
# intl.lib is not compatible with SAFESEH
link_args : noseh_link_args,
include_directories : configinc,
link_with : charset_lib,
link_with : [charset_lib, gnulib_lib],
dependencies : [pcre, thread_dep, libintl, librt] + libiconv + platform_deps,
c_args : ['-DG_LOG_DOMAIN="GLib"', '-DGLIB_COMPILATION', '-DPCRE_STATIC'] + glib_hidden_visibility_args
)

View File

@ -84,7 +84,6 @@ glib_conf.set_quoted('PACKAGE_TARNAME', 'glib')
glib_conf.set_quoted('PACKAGE_URL', '')
glib_conf.set_quoted('PACKAGE_VERSION', meson.project_version())
glib_conf.set('ENABLE_NLS', 1)
glib_conf.set('HAVE_GOOD_PRINTF', 1) # FIXME
# Variables used in glib-gettextize and pkg-config files
# These should not contain " quotes around the values
@ -557,11 +556,15 @@ endif
# AC_FUNC_VSNPRINTF_C99
# Check whether there is a snprintf() function with C99 semantics installed.
# AC_FUNC_SNPRINTF_C99
if host_system == 'windows' and cc.get_id() == 'gcc'
# Unfortunately the mingw implementations of C99-style snprintf and vsnprintf
# don't seem to be quite good enough, at least not in mingw-runtime-3.14.
# (Sorry, I don't know exactly what is the problem, but it is related to
# floating point formatting and decimal point vs. comma.)
have_good_vsnprintf = false
have_good_snprintf = false
if host_system == 'windows'
# Unfortunately the mingw and Visual Studio 2015+ implementations of C99-style
# snprintf and vsnprintf don't seem to be quite good enough, at least not in
# mingw-runtime-3.14. (Sorry, I don't know exactly what is the problem,
# but it is related to floating point formatting and decimal point vs. comma.)
# The simple tests in AC_FUNC_VSNPRINTF_C99 and AC_FUNC_SNPRINTF_C99 aren't
# rigorous enough to notice, though.
glib_conf.set('HAVE_C99_SNPRINTF', false)
@ -608,6 +611,7 @@ main(void)
rres = cc.run(vsnprintf_c99_test_code, name : 'C99 vsnprintf')
if rres.compiled() and rres.returncode() == 0
glib_conf.set('HAVE_C99_VSNPRINTF', 1)
have_good_vsnprintf = true
endif
snprintf_c99_test_code = '''
@ -649,6 +653,7 @@ main(void)
rres = cc.run(snprintf_c99_test_code, name : 'C99 snprintf')
if rres.compiled() and rres.returncode() == 0
glib_conf.set('HAVE_C99_SNPRINTF', 1)
have_good_snprintf = true
endif
endif
@ -658,6 +663,13 @@ else
glib_conf.set('EXEEXT', '')
endif
if have_good_vsnprintf and have_good_snprintf
# Our printf is 'good' only if vsnpintf()/snprintf() supports C99 well enough
glib_conf.set('HAVE_GOOD_PRINTF', 1) # FIXME: Check for HAVE_UNIX98_PRINTF?
else
glib_conf.set('HAVE_VASPRINTF', 1)
endif
# Check whether the printf() family supports Unix98 %n$ positional parameters
# AC_FUNC_PRINTF_UNIX98
# Nothing uses HAVE_UNIX98_PRINTF