I'm trying to set up a SDL2 and C development environment on Windows 10 with MinGW-w64.
When trying to run the basic c app with SDL initialization, it compiles without warnings but fails to run afterwards, again without any warnings. Executable just exits.
Here's the source:
#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...");
}
}
... and the makefile:
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
... and the weird output from 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.
I'm assuming I'm doing something wrong in the linking phase, but can't pinpoint it exactly. On Linux, everything compiles, runs and debugs as expected.
Here's a corrected makefile, as answered which will compile and work fine in Windows console:
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
Aside from startup issue with missing dynamic library, you seem to be mislead (arguably by SDL actually being misleading in that aspect) that your b main
in gdb sets breakpoint in your main
function. That's not the case as SDL redefines main
to SDL_main
, so if you have #include "SDL2.h"
or something similar and SDL have main wrapper implemented for your operating system - your function gets renamed. Internally main
(or wmain
, or WinMain
, or whatever target system uses as user-defined code entry point) is implemented in SDL2main
library that you link with, and it calls SDL_main
(your code).
TL;DR use b SDL_main
in gdb instead.
Second point is why you don't see output text. That's once again windows specific, basically because you've build "GUI" app, which is different from "console" app, and don't really have its stdout
associated with console output. Output is still there but you can't see it - but it can be redirected to other program or file, e.g. your_program.exe | more
or your_program.exe > stdout.txt
. There are ways to reconnect stdout to console (some freopen
with CON
magic, as I recall), or you can just build console program instead with -Wl,-subsystem,console
.
As a side note, -w
compiler flag (that could be loosely read as "don't ever warn me about any potential problems with my code as I'm 100% sure it is absolutely perfect and all your warnings are unjustified complaints about my perfect code" (sorry)) is a really really bad idea, with some very rare exceptions. Compilers, especially gcc and clang, are very good at giving warnings in places where it really matter, allowing you to spot mistakes early. You want more warnings (e.g. -Wall -Wextra
, probably more), not no warnings at all. And while we're at it, OBJS
in makefile logically should mean object files, not sources (of course you technically can call your variables anything you like, it is just misleading).