Aviv Cohn
Aviv Cohn

Reputation: 17193

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

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:

  1. Why does this solve the problem? What does linking with libmingw32.a do that solves this?

  2. 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

Answers (1)

keltar
keltar

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 .os, 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

Related Questions