为什么与 `mingw32` 链接解决了 SDL2 的这个编译问题?

Why does linking with `mingw32` solve this compilation problem with SDL2?

我正在 Windows 和 Mingw 上使用 SDL2 和 C 学习开发。

我尝试了以下命令来编译我的程序:

gcc -IC:C:/msys64_new/mingw64/include/SDL2 *.c -o game.exe -g -Wall -Wno-unused -LC:/msys64_new/mingw64/lib -lSDL2main -lSDL2

它给出了错误:Undefined reference to WinMain

然后我读到我应该在命令中添加-lmingw32

gcc -IC:C:/msys64_new/mingw64/include/SDL2 *.c -o game.exe -g -Wall -Wno-unused -LC:/msys64_new/mingw64/lib -lmingw32 -lSDL2main -lSDL2

现在可以了!我的问题是:

  1. 为什么这样解决问题?与 libmingw32.a 链接能解决这个问题吗?

  2. gcc如何找到libmingw32.a-LC:/msys64_new/mingw64/lib.

  3. 指向的文件夹里好像没有这样的文件

libmingw32 是 C 运行时库的 mingw 实现的一部分,包括例如crt0 和线程本地存储,在调用 main 之前发生的事情。如果你要求 gcc 通过 gcc -v the_rest_of_your_build_command 告诉你它在后台做了什么,你会发现它的 linking 命令中有 -lmingw32 ;可以删除 CRT(和 CRT0),但这是另一个问题(并且您需要特殊处理,因为普通的 C 程序期望 CRT 存在)。

有一些预定义的路径 linker 在其中搜索库。从历史上看,类 unix 系统有 /lib/usr/lib 等。由于 mingw 大部分只是移植的 gcc 工具链,它继承了相同的路径,只是带有它的安装目录前缀(例如 c:\mingw-w64\x86_64-w64-mingw32\lib。检查 ld --verbose 输出,特别是 SEARCH_DIR

现在为什么你需要指定 -lmingw32,即使它在那里 - 唯一的原因是 ld linker 如何解决依赖关系 - 基本上是从左到右的规则。如果一个静态库依赖于另一个静态库,则需要首先在库列表中指定它(但可以多次指定,不会产生冲突)。在您的情况下,#include <SDL.h> 将您的 main 函数重新定义为 SDL_main;这样你的程序就不再有定义的入口点,但是 libSDL2main.a 有一个 - 简单的 mainWinMain 做最少的准备并调用你的 SDL_main。因此,您需要 link 和 -lSDL2main,但默认情况下,-lmingw32 附加在最后(导致例如 -lSDL2main -lSDL2 -lmingw32),并且 link 不要搜索对于 SDL2mainWinMain 的定义,而您的 .o 中没有 WinMain,因此出现 linking 错误。如果你添加 -lmingw32 -lSDL2main -lSDL2,你有正确的依赖链——CRT0 依赖于 WinMain,它在 SDL2main 中实现,它也依赖于 SDL2。默认参数仍会在尾部添加 -lmingw32,因此您将隐含地拥有它两次,但正如我之前所说,您可以这样做。