基本 SDL2 应用程序可以使用 MinGW-w64 编译,但不能 运行
Basic SDL2 app compiles with MinGW-w64 but doesn't run
我正在尝试使用 MinGW-w64 在 Windows 10 上设置 SDL2 和 C 开发环境。
当尝试 运行 具有 SDL 初始化的基本 c 应用程序时,它编译时没有警告,但之后 运行 失败,再次没有任何警告。可执行文件刚刚退出。
来源如下:
#include<SDL2/SDL.h>
int main(int argc, char* argv[]) {
puts("\nmain...\n");
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("\nInit error: %s\n", SDL_GetError());
}
else {
puts("\nSDL init success...");
}
}
... 和生成文件:
OBJS = sdl_init.c
EXE_NAME = sdl_init_test
CFLAGS_W = -w -Wl,-subsystem,windows
LFLAGS_W = -lmingw32 -lSDL2main -lSDL2
INCS_W = -IC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\include
LIBS_W = -LC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\lib
windows_debug:
gcc $(OBJS) $(INCS_W) $(LIBS_W) $(CFLAGS_W) $(LFLAGS_W) -g -o $(EXE_NAME).exe
...以及 gdb 的奇怪输出:
Reading symbols from .\sdl_init_test.exe...
(gdb) list main
12 ../../src/mingw-w64-crt/crt/crt0_c.c: No such file or directory.
(gdb) b main
Breakpoint 1 at 0x402e70: file ../../src/mingw-w64-crt/crt/crt0_c.c, line 17.
我假设我在链接阶段做错了什么,但无法准确指出。
在 Linux 上,一切都按预期编译、运行 和调试。
这是一个更正的 makefile,如 将在 Windows 控制台中正常编译和工作:
SRC = sdl_init.c
EXE_NAME = sdl_init_test
CFLAGS_W = -Wall -Wl,-subsystem,console
LFLAGS_W = -lmingw32 -lSDL2main -lSDL2
INCS_W = -IC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\include
LIBS_W = -LC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\lib
windows_debug:
gcc $(SRC) $(INCS_W) $(LIBS_W) $(CFLAGS_W) $(LFLAGS_W) -g -o $(EXE_NAME).exe
除了缺少动态库的启动问题外,您似乎被误导了(可以说是 SDL 实际上在这方面具有误导性)您在 gdb 中的 b main
在 您的 [= 中设置了断点40=] main
函数。这不是 SDL redefines main
到 SDL_main
的情况,所以如果你有 #include "SDL2.h"
或类似的东西并且 SDL 为你的操作系统实现了主要包装 - 你的函数被重命名.在内部 main
(或 wmain
,或 WinMain
,或任何目标系统用作 user-defined 代码入口点)在 SDL2main
库中实现,您 link 并调用 SDL_main
(您的代码)。
TL;DR 在 gdb 中使用 b SDL_main
。
第二点是您看不到输出文本的原因。这又是 windows 特定的,主要是因为您构建了“GUI”应用程序,它不同于“控制台”应用程序,并且其 stdout
并没有真正与控制台输出相关联。输出仍然存在,但您看不到它 - 但它可以重定向到其他程序或文件,例如your_program.exe | more
或 your_program.exe > stdout.txt
。有一些方法可以将 stdout 重新连接到控制台(我记得有些 freopen
具有 CON
魔法),或者您可以只构建控制台程序而不是 -Wl,-subsystem,console
.
作为旁注,-w
编译器标志(可以粗略地理解为“永远不要警告我我的代码有任何潜在问题,因为我 100% 确定它绝对完美并且你所有的警告都是对我完美代码的无理抱怨”(抱歉))是一个非常非常糟糕的主意,除了一些非常罕见的例外。编译器,尤其是 gcc 和 clang,非常擅长在真正重要的地方发出警告,让您及早发现错误。您想要更多警告(例如 -Wall -Wextra
,可能更多),而不是根本没有警告。当我们讨论它时,makefile 中的 OBJS
在逻辑上应该表示目标文件,而不是源文件(当然,从技术上讲,您可以随意调用您的变量,这只是误导)。
我正在尝试使用 MinGW-w64 在 Windows 10 上设置 SDL2 和 C 开发环境。
当尝试 运行 具有 SDL 初始化的基本 c 应用程序时,它编译时没有警告,但之后 运行 失败,再次没有任何警告。可执行文件刚刚退出。
来源如下:
#include<SDL2/SDL.h>
int main(int argc, char* argv[]) {
puts("\nmain...\n");
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("\nInit error: %s\n", SDL_GetError());
}
else {
puts("\nSDL init success...");
}
}
... 和生成文件:
OBJS = sdl_init.c
EXE_NAME = sdl_init_test
CFLAGS_W = -w -Wl,-subsystem,windows
LFLAGS_W = -lmingw32 -lSDL2main -lSDL2
INCS_W = -IC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\include
LIBS_W = -LC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\lib
windows_debug:
gcc $(OBJS) $(INCS_W) $(LIBS_W) $(CFLAGS_W) $(LFLAGS_W) -g -o $(EXE_NAME).exe
...以及 gdb 的奇怪输出:
Reading symbols from .\sdl_init_test.exe...
(gdb) list main
12 ../../src/mingw-w64-crt/crt/crt0_c.c: No such file or directory.
(gdb) b main
Breakpoint 1 at 0x402e70: file ../../src/mingw-w64-crt/crt/crt0_c.c, line 17.
我假设我在链接阶段做错了什么,但无法准确指出。 在 Linux 上,一切都按预期编译、运行 和调试。
这是一个更正的 makefile,如
SRC = sdl_init.c
EXE_NAME = sdl_init_test
CFLAGS_W = -Wall -Wl,-subsystem,console
LFLAGS_W = -lmingw32 -lSDL2main -lSDL2
INCS_W = -IC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\include
LIBS_W = -LC:\MinGW\devlibs\SDL2-2.0.12\x86_64-w64-mingw32\lib
windows_debug:
gcc $(SRC) $(INCS_W) $(LIBS_W) $(CFLAGS_W) $(LFLAGS_W) -g -o $(EXE_NAME).exe
除了缺少动态库的启动问题外,您似乎被误导了(可以说是 SDL 实际上在这方面具有误导性)您在 gdb 中的 b main
在 您的 [= 中设置了断点40=] main
函数。这不是 SDL redefines main
到 SDL_main
的情况,所以如果你有 #include "SDL2.h"
或类似的东西并且 SDL 为你的操作系统实现了主要包装 - 你的函数被重命名.在内部 main
(或 wmain
,或 WinMain
,或任何目标系统用作 user-defined 代码入口点)在 SDL2main
库中实现,您 link 并调用 SDL_main
(您的代码)。
TL;DR 在 gdb 中使用 b SDL_main
。
第二点是您看不到输出文本的原因。这又是 windows 特定的,主要是因为您构建了“GUI”应用程序,它不同于“控制台”应用程序,并且其 stdout
并没有真正与控制台输出相关联。输出仍然存在,但您看不到它 - 但它可以重定向到其他程序或文件,例如your_program.exe | more
或 your_program.exe > stdout.txt
。有一些方法可以将 stdout 重新连接到控制台(我记得有些 freopen
具有 CON
魔法),或者您可以只构建控制台程序而不是 -Wl,-subsystem,console
.
作为旁注,-w
编译器标志(可以粗略地理解为“永远不要警告我我的代码有任何潜在问题,因为我 100% 确定它绝对完美并且你所有的警告都是对我完美代码的无理抱怨”(抱歉))是一个非常非常糟糕的主意,除了一些非常罕见的例外。编译器,尤其是 gcc 和 clang,非常擅长在真正重要的地方发出警告,让您及早发现错误。您想要更多警告(例如 -Wall -Wextra
,可能更多),而不是根本没有警告。当我们讨论它时,makefile 中的 OBJS
在逻辑上应该表示目标文件,而不是源文件(当然,从技术上讲,您可以随意调用您的变量,这只是误导)。