Почему соединение с `mingw32` решает эту проблему компиляции с SDL2? - PullRequest
2 голосов
/ 20 марта 2020

Я изучаю разработку с использованием SDL2 с C на Windows и Mingw.

Я попытался скомпилировать свою программу с помощью следующей команды:

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.

1 Ответ

2 голосов
/ 23 марта 2020

libmingw32 является частью реализации mingw библиотеки C времени выполнения, включая, например, crt0 и локальное хранилище потока, что происходит до вызова main. Если вы попросите g cc сообщить вам, что он делает под капотом через gcc -v the_rest_of_your_build_command, вы увидите, что в любом случае в его команде связывания есть -lmingw32; можно отбросить CRT (и CRT0), но это для другого вопроса (и вам понадобится специальная обработка, поскольку обычные C программы ожидают наличия CRT).

Существуют некоторые предопределенные пути, которые ищет компоновщик путей библиотеки в. Исторически для unix -подобных систем есть /lib, /usr/lib и так далее. Поскольку mingw в основном является просто портированным набором инструментов g cc, он наследует те же пути, только с префиксом каталога установки (например, c:\mingw-w64\x86_64-w64-mingw32\lib. Проверьте вывод ld --verbose, в частности SEARCH_DIR.

Теперь почему вам нужно указать -lmingw32, даже если он в любом случае есть - единственная причина в том, как компоновщик ld разрешает зависимости - правило слева направо. Если одна библиотека stati c зависит от другой, ее нужно сначала указать в библиотеках список (но может быть указан несколько раз, это не приведет к конфликту). В вашем случае #include <SDL.h> переопределяет вашу main функцию на SDL_main; таким образом, ваша программа больше не имеет определенной точки входа, но libSDL2main.a есть один - простой main или WinMain, который выполняет минимальную подготовку и вызывает ваш SDL_main. Таким образом, вам нужно связать с -lSDL2main, но по умолчанию -lmingw32 добавляется последним (в результате, например, * 1025) *), и компоновщик не ищет определение WinMain в SDL2main, и в ваших .o s нет WinMain, следовательно, возникает ошибка компоновки. Если вы добавите -lmingw32 -lSDL2main -lSDL2, вы получите правильное значение цепочка зависимостей - CRT0 зависит от WinMain, который реализован в SDL2main, который также зависит от SDL2. Параметры по умолчанию все равно добавят -lmingw32 в хвост, так что вы неявно получите его дважды, но, как я уже говорил, вам разрешено это сделать.

...