Приложение Basi c SDL2 компилируется с MinGW-w64, но не запускается - PullRequest
1 голос
/ 04 августа 2020

Я пытаюсь настроить среду разработки SDL2 и C на Windows 10 с помощью MinGW-w64.

При попытке запустить приложение basi c c с инициализацией SDL , он компилируется без предупреждений, но потом не запускается, опять же без предупреждений. Исполняемый файл просто завершается.

Вот источник:

#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...");
    }
}

... и make-файл:

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 все компилируется, запускается и отлаживается должным образом.

Вот исправленный make-файл, как ответил , который будет компилироваться и нормально работать в консоли 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

1 Ответ

1 голос
/ 05 августа 2020

Помимо проблемы запуска с отсутствующей библиотекой Dynami c, вы, похоже, вводите в заблуждение (возможно, из-за того, что SDL фактически вводит в заблуждение в этом аспекте), что ваш b main в gdb устанавливает точку останова в вашем main функция. Это не так, поскольку SDL переопределяет main на SDL_main, поэтому, если у вас есть #include "SDL2.h" или что-то подобное, и в SDL есть основная оболочка, реализованная для вашей операционной системы - ваша функция будет переименована. Внутренне main (или wmain, или WinMain, или любая другая целевая система, использующая в качестве точки входа определяемого пользователем кода) реализовано в библиотеке SDL2main, с которой вы связываетесь, и вызывает SDL_main (ваш код) .

TL; DR используйте вместо него b SDL_main в gdb.

Второй момент - почему вы не видите выходной текст. Это еще раз windows указывает c, в основном потому, что вы создали приложение «GUI», которое отличается от «консольного» приложения, и на самом деле его stdout не связано с выводом на консоль. Вывод все еще есть, но вы его не видите, но его можно перенаправить в другую программу или файл, например, your_program.exe | more или your_program.exe > stdout.txt. Есть способы повторно подключить stdout к консоли (некоторые freopen с CON magi c, насколько я помню), или вы можете просто создать консольную программу вместо -Wl,-subsystem,console.

В качестве примечания , -w флаг компилятора (который можно примерно прочитать как «никогда не предупреждайте меня о каких-либо потенциальных проблемах с моим кодом, поскольку я на 100% уверен, что он абсолютно идеален, и все ваши предупреждения являются необоснованными жалобами на мой идеальный код» (извините)) - действительно плохая идея, за очень редкими исключениями. Компиляторы, особенно g cc и clang, очень хороши в выдаче предупреждений в тех местах, где это действительно важно, что позволяет вам рано обнаруживать ошибки. Вам нужно больше предупреждений (например, -Wall -Wextra, возможно, больше), а не вообще никаких предупреждений. И пока мы это делаем, OBJS в make-файле логически должно означать объектные файлы, а не источники (конечно, технически вы можете называть свои переменные как угодно, это просто вводит в заблуждение).

...