静态链接 GLFW 时未定义对“__ms_vsnprintf”的引用

Undefined reference to `__ms_vsnprintf' when linking GLFW statically

我正在尝试使用 mingw 在 windows 8 64 位中编译 GLFW 快速入门指南 (Here)。我正在使用来自 glfw 网站的官方 32 位 windows 二进制文件。

当我通过 linking -lglfw3dll -lgdi32 -lopengl32 -lglew32 和定义 GLFW_DLL.

动态地 link glfw 库时一切正常

但是,当我尝试静态 link glfw 时,我得到 undefined reference to '__ms_vsnprintf'

我对 link 的静态命令是 mingw32-g++.exe -o bin\Release\test.exe obj\Release\main.o -s -lglfw3 -lgdi32 -lopengl32 -lglew32s,定义了 GLEW_STATIC

我在尝试为 GLFW 构建示例应用程序时遇到了同样的问题。我将编译器套件从原来的 MinGW32 切换到 MinGW-W64,这解决了问题。我在读完这个 post:

后想出了这个主意

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

似乎 GLFW 库是使用 MinGW64 或 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);

所以只要在它们前面加上下划线就可以了。

我在 Linux 上与 --host=i686-w64-mingw32.

交叉编译 GMP for Windows32 时遇到了这个问题

因为我不想弄乱 GMP 的源代码或构建系统,而且我没有选择在 Windows32 上使用什么工具链,

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

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

无论如何,我更喜欢 C99 兼容版本。请注意,无论如何,变通方法都会拖拽 ___mingw_vsnprintf,即即使在目标代码不使用 vsnprintf.

的情况下

mingw版本由libmingwex.a提供;您会看到 gcc 与 -Wl,-v 链接,它打印 -lmingwex (以及许多其他内容)。

问题可能是项目的配置在确定主机的 vsnprintf 是否正常工作,或者用户是否想坚持使用 MS 的东西或符合 C99 的功能方面存在一些问题。无论如何,我的 i686-w64-mingw32 交叉工具的 stdio.h 以及主机上的 stdio.h 都有受

保护的部分
#if __USE_MINGW_ANSI_STDIO
/*
 * User has expressed a preference for C99 conformance...
 */
...
#ifdef _GNU_SOURCE

然后将 vsnprintf 定义为对 __mingw_vsnprintf 调用或 __ms_vsnprintf 调用的包装。因此也应该对构建系统进行黑客攻击并在某处注入 -D__USE_MINGW_ANSI_STDIO

在 autotools 的情况下,在 GMP 的情况下对我有用的是配置

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

重新配置、构建和安装后,nm libgmp.a | grep vsnprintf 显示构建的库

         U ___mingw_vsnprintf

代替之前的

         U ___ms_vsnprintf