Undefined reference to __ms_vsnprintf.
Georg-Johann Lay
avr at gjlay.de
Mon Feb 24 10:14:43 UTC 2020
Hi, I am running into an undefined reference when I am using gmp_printf
like in the following test case:
#include <stdio.h>
#include <gmp.h>
int main()
{
mpz_t z;
mpz_init_set_si (z, 123);
gmp_printf ("z = %Zd\n", z);
mpz_clear (z);
return 0;
}
Linking under Windos:
.../lib/libgmp.a(doprntf.o):doprntf.c:(.text+0x24): undefined reference
to `__ms_vsnprintf'
Adding -Wl,-v to the compilation:
...ld.exe ... -lgmp -v -lmingw32 -lgcc -lm
oldname -lmingwex -lmsvcrt -ladvapi32 -lshell32 -luser32 -lkernel32
-lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt
So all stuff appears to be present, in particular libmingwex.a.
Any hints what's going wrong here?
stdio.h reads:
/*
* Formatted Output
*
* MSVCRT implementations are not ANSI C99 conformant...
* we offer these conforming alternatives from libmingwex.a
*/
#undef __mingw_stdio_redirect__
#define __mingw_stdio_redirect__(F) __cdecl __MINGW_NOTHROW __mingw_##F
extern int __mingw_stdio_redirect__(fprintf)(FILE*, const char*, ...);
...
extern int __mingw_stdio_redirect__(vsnprintf)(char*, size_t, const
char*, __VALIST);
Consequently, I can work around the problem by linking with:
-Wl,-u,___mingw_vsnprintf
-Wl,--defsym,___ms_vsnprintf=___mingw_vsnprintf
and it appears to work as expected.
So is this a glitch in GMP build machinery?
I configured and built that libgmp.a on linux with:
$ ../../source/gmp-6.1.2/configure --host=i686-w64-mingw32 --prefix=...
--with-gnu-ld --enable-cxx --enable-static --disable-shared
That i686-w64-mingw32 toolchain's stdio.h also defines __mingw_vsnprintf:
extern __attribute__((__format__ (gnu_printf, 3, 0)))
__MINGW_ATTRIB_NONNULL(3)
int __cdecl __mingw_vsnprintf(char * __restrict__ _DstBuf,size_t
_MaxCount,const char * __restrict__ _Format, va_list _ArgList);
however it depends on macro __USE_MINGW_ANSI_STDIO (and maybe also
_GNU_SOURCE, I am a bit lost in them nested macros):
#if __USE_MINGW_ANSI_STDIO
/*
* User has expressed a preference for C99 conformance...
*/
...
__mingw_ovr
__attribute__((__format__ (gnu_printf, 3, 4))) __MINGW_ATTRIB_NONNULL(3)
int snprintf (char *__stream, size_t __n, const char *__format, ...)
{
register int __retval;
__builtin_va_list __local_argv; __builtin_va_start( __local_argv,
__format );
__retval = __mingw_vsnprintf( __stream, __n, __format, __local_argv );
__builtin_va_end( __local_argv );
return __retval;
}
...
#if !defined (__USE_MINGW_ANSI_STDIO) || __USE_MINGW_ANSI_STDIO == 0
/* this is here to deal with software defining
* vsnprintf as _vsnprintf, eg. libxml2. */
#pragma push_macro("snprintf")
#pragma push_macro("vsnprintf")
# undef snprintf
# undef vsnprintf
int __cdecl __ms_vsnprintf(char * __restrict__ d,size_t n,const char
* __restrict__ format,va_list arg)
__MINGW_ATTRIB_DEPRECATED_MSVC2005 __MINGW_ATTRIB_DEPRECATED_SEC_WARN;
__mingw_ovr
__MINGW_ATTRIB_NONNULL(3)
int vsnprintf (char * __restrict__ __stream, size_t __n, const char *
__restrict__ __format, va_list __local_argv)
{
return __ms_vsnprintf (__stream, __n, __format, __local_argv);
}
...
Is this a glitch in GMP's configure and __USE_MINGW_ANSI_STDIO should be
set? Or can / should I do that by hand and where?
I am using that i686-w64-mingw32 toolchain successfully to build much
larger projects for Windos / MinGW like GCC, so it appears to work
reasonably well.
Thanks for your support,
Johann
More information about the gmp-discuss
mailing list