简体   繁体   中英

Undefined reference to `__ms_vsnprintf' when linking GLFW statically

I am trying to compile the GLFW quickstart guide ( Here ) in windows 8 64-bit using mingw. I am using the official 32 bit windows binary from the glfw website.

Everything works fine when I link the glfw library dynamically by linking -lglfw3dll -lgdi32 -lopengl32 -lglew32 and defining GLFW_DLL .

When I try to link glfw statically, however, I get undefined reference to '__ms_vsnprintf'

My command to link statically is mingw32-g++.exe -o bin\\Release\\test.exe obj\\Release\\main.o -s -lglfw3 -lgdi32 -lopengl32 -lglew32s with GLEW_STATIC defined.

I got the same problem when I tried to build an example app for GLFW. I switched the compiler suite from original MinGW32 to MinGW-W64 and that solved the problem. I came up with that idea after reading this post:

http://mingw-users.1079350.n2.nabble.com/missing-symbol-ms-vsnprintf-when-linking-with-cross-compiled-library-td7582798.html

Seems the GLFW libs are build with a MinGW64 or MinGW-W64.

MinGW\\include\\stdio.h :

/* The following pair ALWAYS refer to the MSVCRT implementations...
 */
_CRTIMP int __cdecl __MINGW_NOTHROW _snprintf (char*, size_t, const char*, ...);
_CRTIMP int __cdecl __MINGW_NOTHROW _vsnprintf (char*, size_t, const char*, __VALIST);
_CRTIMP int __cdecl __MINGW_NOTHROW _vscprintf (const char*, __VALIST);

So just use them with underscore in front of them.

I encountered that problem when cross-compiling GMP on Linux for Windos32 with --host=i686-w64-mingw32 .

As I don't want to mess with GMP's sources or build system, and I have no choice what toolchain to use on Windos32,

I figured out the following work-around: When linking, link with

-Wl,-u,___mingw_vsnprintf -Wl,--defsym,___ms_vsnprintf=___mingw_vsnprintf

I am preferring a C99 compliant version, anyway. Notice that that work-around will drag ___mingw_vsnprintf no matter what, ie even in the case the target code does not use vsnprintf .

The mingw version is provided by libmingwex.a ; you see that gcc links against it with -Wl,-v which prints -lmingwex (among many others).

The problem might be that the project's configure has some problems figuring out whether the host's vsnprintf is working properly or not, or whether the user wants to stick with MS stuff or functions that are C99 compliant. Anyway, stdio.h of my i686-w64-mingw32 cross-tools as well as the stdio.h on the host have sections that are secured by

#if __USE_MINGW_ANSI_STDIO
/*
 * User has expressed a preference for C99 conformance...
 */
...
#ifdef _GNU_SOURCE

and then define vsnprintf as a wrapper around a call to __mingw_vsnprintf or around a call to __ms_vsnprintf . Hence there should also be hacks to the build system and inject -D__USE_MINGW_ANSI_STDIO somewhere.

In the case of autotools, and what worked for me in the case of GMP, is to configure

$(srcdir)/configure CPPFLAGS='-D__USE_MINGW_ANSI_STDIO' ...

After re-configure, build and install, nm libgmp.a | grep vsnprintf nm libgmp.a | grep vsnprintf shows for the built libraries

         U ___mingw_vsnprintf

instead of the previous

         U ___ms_vsnprintf

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM