Reputation: 17193
I'm learning development using SDL2 with C on Windows and Mingw.
I tried the following command to compile my program:
gcc -IC:C:/msys64_new/mingw64/include/SDL2 *.c -o game.exe -g -Wall -Wno-unused -LC:/msys64_new/mingw64/lib -lSDL2main -lSDL2
It gave the error: Undefined reference to WinMain
Then I read that I should add -lmingw32
to the command:
gcc -IC:C:/msys64_new/mingw64/include/SDL2 *.c -o game.exe -g -Wall -Wno-unused -LC:/msys64_new/mingw64/lib -lmingw32 -lSDL2main -lSDL2
And now it works! My questions are:
Why does this solve the problem? What does linking with libmingw32.a
do that solves this?
How does gcc
find libmingw32.a
? I don't seem to have such a file in the folder directed by -LC:/msys64_new/mingw64/lib
.
Upvotes: 3
Views: 1617
Reputation: 18399
libmingw32 is a part of mingw implementation of C runtime library, including e.g. crt0 and thread-local storage, stuff happening before your main
is called. If you ask gcc to inform you what it does under the hood via gcc -v the_rest_of_your_build_command
you'll see that it have -lmingw32
anyway in its linking command; it is possible to drop CRT (and CRT0) but that's for another question (and you'll need special handling since ordinary C programs expect CRT to be present).
There are some predefined paths linker search for libraries in. Historically for unix-like systems there are /lib
, /usr/lib
and so on. As mingw is mostly just ported gcc toolchain it inherits the same paths, just with its installation directory prefix (e.g. c:\mingw-w64\x86_64-w64-mingw32\lib
. Check outout of ld --verbose
output, specifically SEARCH_DIR
.
Now why you need to specify -lmingw32
even though it is there anyway - the only reason is how ld linker resolves dependencies - left to right rule, basically. If one static library depends on another, it needs to be specified first in libraries list (but can be specified multiple times, it will not produce a conflict). In your case, #include <SDL.h>
redefines your main
function to SDL_main
; that way your program don't have defined entry point anymore, but libSDL2main.a
have one - simple main
or WinMain
that does minimal preparation and calls your SDL_main
. So, you need to link with -lSDL2main
, but by default -lmingw32
is appended last (resulting in e.g. -lSDL2main -lSDL2 -lmingw32
), and linker don't search for definition of WinMain
in SDL2main
, and there is no WinMain
in your .o
s, hence linking error. If you add -lmingw32 -lSDL2main -lSDL2
, you have correct dependency chain - CRT0 depends on WinMain
which implemented in SDL2main
which also depends on SDL2
. Default parameters will still add -lmingw32
at the tail, so you'll implicitly have it twice, but as I've said before you're allowed to do so.
Upvotes: 5