Undefined reference to `__ms_vsnprintf' when linking GLFW statically
Asked Answered
F

4

3

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.

Felipa answered 22/3, 2015 at 20:53 Comment(1)
I got past this problem by compiling the GLFW libraries myself. I still don't know why this was happening though.Felipa
A
3

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:

https://sourceforge.net/p/mingw/mailman/mingw-users/thread/83ha2x1i7k.fsf%40gnu.org/

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

Appetitive answered 23/4, 2015 at 21:57 Comment(0)
R
1

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.

Rab answered 29/11, 2015 at 6:42 Comment(0)
R
1

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, i.e. 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 shows for the built libraries

         U ___mingw_vsnprintf

instead of the previous

         U ___ms_vsnprintf
Reify answered 24/2, 2020 at 16:19 Comment(0)
P
1

I'm aware this topic is very old, but the solution in my situation was to run make clean && make to remove old object files (.o) compiled with an incompatible version of GCC.

Pheon answered 7/6, 2023 at 12:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.