[Newbie] SDL on Windows builing issues

Dear All,

I have already used SDL years ago but now I want to use them agani with my student in a School Project (we will design and develop a simple game), but please consider me a newbie.

The school uses Dev-C++ but I am facing issues in building SDL program. I have read:
. Lazy’s tutorial - Lazy Foo' Productions - Setting up SDL 2 on MinGW
. Slater’s tutorial - SDL Setup For Dev C++
but they seems outdated or at least they did not work for me.

I tried latest SDL release (SDL 2.28.4 at the time of writing) but according to the build enviroment (Dev-C++, RedPanda-Dev-C++, and Red Panda C++) I had different error messages…

  1. I wonder if I am using 32/64 bit version of SDL2/MiniGW suite or if there are some specific version that I should use.
  2. It seems that SDL 2.28.4 has reference to build release enviroment because I get reference to /Users/valve/release/ as you can see from the logs ‘C:/Program Files (x86)/Dev-Cpp/MinGW64/bin/…/lib/gcc/x86_64-w64-mingw32/10.3.0/…/…/…/…/x86_64-w64-mingw32/bin/ld.exe: C:\Users\stefy\Desktop\SDL2-2.28.4\x86_64-w64-mingw32\lib\libSDL2.a(SDL_windowsevents.o): in function `WIN_WindowProc’:
    /Users/valve/release/SDL2/SDL2-2.28.4-source/foo-x64/…/src/video/windows/SDL_windowsevents.c:1311: ’ is ti correct?

Following the code and the command line used…

Most common issue - RedPanda-Dev-C++ I get

C:/Program Files (x86)/Dev-Cpp/MinGW64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\stefy\Desktop\SDL2-2.28.4\x86_64-w64-mingw32\lib\libSDL2.a(SDL_hidapi.o): in function `PLATFORM_hid_enumerate':
/Users/valve/release/SDL2/SDL2-2.28.4-source/foo-x64/../src/hidapi/windows/hid.c:388: undefined reference to `__imp_SetupDiGetClassDevsA'

the command used was

"C:\xampp\sdl\sdl.cpp" -o "C:\xampp\sdl\sdl.exe" -Wall -Wextra -g3 -finput-charset=windows-1252 -fexec-charset=windows-1252 -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\include\c++\10.3.0" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\include\c++\10.3.0\x86_64-w64-mingw32" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\include\c++\10.3.0\backward" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\lib\gcc\x86_64-w64-mingw32\10.3.0\include" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\include" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\lib\gcc\x86_64-w64-mingw32\10.3.0\include-fixed" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\x86_64-w64-mingw32\include" -I"C:\Users\stefy\Desktop\SDL2-2.28.4\x86_64-w64-mingw32\include\SDL2" -L"C:\Program Files (x86)\Dev-Cpp\MinGW64\lib" -L"C:\Program Files (x86)\Dev-Cpp\MinGW64\x86_64-w64-mingw32\lib" -L"C:\Users\stefy\Desktop\SDL2-2.28.4\x86_64-w64-mingw32\lib" -g3 -w -Wl,-subsystem,windows -lmingw32 -lSDL2 -lSDL2main -static

Here is the code that I used for hello world:

#include "SDL.h"

int main( int argc, char* args[] )
{
	//Start SDL
	SDL_Init( SDL_INIT_EVERYTHING );
	
	//Quit SDL
	SDL_Quit();
	
	return 0;    
}

P.S.: I would upload the full build log but I cannot because I am new user of the forum

Hi,

I got it run with a “fresh installed” Dev-C++ 4.9.9.2 and mingw64 12.2.0.

Tools->Compiler Options->Directories
Binaries: Set a path to the bin directory of mingw64
Libraries: Set a path to the lib directory of mingw64
Set a second path to …/SDL2-2.28.4/x86_64-w64-mingw32/lib
C includes: Set a path to mingw64/include
Set a second path to …/SDL2-2.28.4\x86_64-w64-mingw32\include

Tools->Compiler Options-> “Add these commands to the linker command line”
Activate the checkbox and set the following commands:
-lSDL2main -lSDL2

copy SDL2.dll to your output directory

I use the following test source:

#define SDL_MAIN_HANDLED // avoid  "undefined reference to 'WinMain'"
#include <stdio.h>
#include <stdlib.h>
#include "SDL2/sdl.h"

int main(int argc, char *argv[])
{
    printf("Hello world\n");
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) == 0) {
        printf("SDL INIT OK\n");    
    } else {
        printf("SDL INIT ERROR\n");   
    }
    SDL_Quit();
    
    while(1);
}

Best regards
Mik

If you define SDL_MAIN_HANDLED you should call SDL_SetMainReady.

1 Like

You got __imp_SetupDiGetClassDevsA undefined reference, because you missing link to Windows’ SetupAPI library. Pass -lSetupAPI to your linker.

You can use pastebin if you still unable to upload it here.

Thank you adding -lSetupAPI worked but it seems that I am missing other libraries beacuse I get this

- Command: g++.exe "C:\xampp\sdl\sdl.cpp" -o "C:\xampp\sdl\sdl.exe" -Wall -Wextra -g3 -finput-charset=windows-1252 -fexec-charset=windows-1252 -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\include\c++\10.3.0" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\include\c++\10.3.0\x86_64-w64-mingw32" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\include\c++\10.3.0\backward" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\lib\gcc\x86_64-w64-mingw32\10.3.0\include" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\include" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\lib\gcc\x86_64-w64-mingw32\10.3.0\include-fixed" -I"C:\Program Files (x86)\Dev-Cpp\MinGW64\x86_64-w64-mingw32\include" -I"C:\Users\stefy\Desktop\SDL2-2.28.4\x86_64-w64-mingw32\include\SDL2" -L"C:\Program Files (x86)\Dev-Cpp\MinGW64\lib" -L"C:\Program Files (x86)\Dev-Cpp\MinGW64\x86_64-w64-mingw32\lib" -L"C:\Users\stefy\Desktop\SDL2-2.28.4\x86_64-w64-mingw32\lib" -g3 -w -lSDL2 -lSDL2main -lSetupAPI -static
C:/Program Files (x86)/Dev-Cpp/MinGW64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:\Users\stefy\Desktop\SDL2-2.28.4\x86_64-w64-mingw32\lib\libSDL2.a(SDL_windows.o): in function `WIN_CoInitialize':
/Users/valve/release/SDL2/SDL2-2.28.4-source/foo-x64/../src/core/windows/SDL_windows.c:102: undefined reference to `__imp_CoInitializeEx'

Any clue?

That’s CoInitializeEx from Ole32 (-lOle32). You can find corresponding libraries from your error messages:
undefined reference to __imp_CoInitializeEx ==> CoInitializeEx ==> Search | Microsoft Learn ==> Library Ole32.lib
Anyways, it’s strange that your gcc miss link to default libs, the gcc from MSYS2 does not have such problem, maybe you got tweaked/outdated compiler?

It seems that the issue is that I’m using a “static-version” (see: SDL2 linking issue ) of SDL2 thus I have to provides ALL the libraries to the linker. At the moment i can compile by using the following linker options

-w -lSDL2 -lSDL2main -lSetupAPI -lole32 -lgdi32 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lwinmm -limm32 -loleaut32 -lshell32 -lversion -luuid

BTW, if you think that the problem is the toolchain hereafter I am sharing the output of g++ -v

Using built-in specs.
COLLECT_GCC=C:\Program Files (x86)\Dev-Cpp\MinGW64\bin\g++.exe
COLLECT_LTO_WRAPPER=C:/Program\ Files\ (x86)/Dev-Cpp/MinGW64/bin/../lib/gcc/x86_64-w64-mingw32/10.3.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-10.3.0/configure --prefix=/mingw64 --with-local-prefix=/mingw64/local --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --with-native-system-header-dir=/mingw64/x86_64-w64-mingw32/include --libexecdir=/mingw64/lib --enable-bootstrap --enable-checking=release --with-arch=x86-64 --with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++,jit --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts=yes --enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --enable-lto --enable-libgomp --disable-multilib --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --with-libiconv --with-system-zlib --with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64 --with-isl=/mingw64 --with-pkgversion='Rev5, Built by MSYS2 project' --with-bugurl=https://github.com/msys2/MINGW-packages/issues --with-gnu-as --with-gnu-ld --with-boot-ldflags='-pipe -Wl,--dynamicbase,--high-entropy-va,--nxcompat,--default-image-base-high -Wl,--disable-dynamicbase -static-libstdc++ -static-libgcc' 'LDFLAGS_FOR_TARGET=-pipe -Wl,--dynamicbase,--high-entropy-va,--nxcompat,--default-image-base-high' --enable-linker-plugin-flags='LDFLAGS=-static-libstdc++\ -static-libgcc\ -pipe\ -Wl,--dynamicbase,--high-entropy-va,--nxcompat,--default-image-base-high\ -Wl,--stack,12582912'
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.3.0 (Rev5, Built by MSYS2 project)

Yep, I’m aware of this, and I realized I used sdl2-config --static-libs to get all the libs SDL need. So, my assumption on the toolchain issue was wrong, but your gcc 10.3.0 is fairly old tho :slightly_smiling_face:.

Does it mean that if I compile SDL2 on my own with --static-libs I won’t need all the “flags” on my linker configuration?

No, the sdl2-config is not a configure, it’s a script used to get installed SDL2’s cflags and/or libs.
You can avoid manual dependency management by using this script in your Makefile. Also the target SDL2::SDL2-static from CMake SDL package will work too.

1 Like

I am not going to use the script at moment, thank you :slight_smile:

BTW, I managed to configure SDL with CLlion by manually configuring CMake… (and it is working)

1 Like

For anyone wondering of an alternative solution instead of linking everything manually:

Linking against libSDL2.dll.a instead would not require all the extra linking flags.

cmake_minimum_required(VERSION 3.25)
project(CMake_Test C)

set(CMAKE_C_STANDARD 99)

include_directories(${PROJECT_SOURCE_DIR}/include)
add_executable(CMake_Test WIN32 main.c)

#target_link_libraries(CMake_Test ${PROJECT_SOURCE_DIR}/lib/libSDL2main.a ${PROJECT_SOURCE_DIR}/lib/libSDL2.a SetupAPI ole32 gdi32 imagehlp dinput8 dxguid dxerr8 user32 winmm imm32 oleaut32 shell32 version uuid)
target_link_libraries(CMake_Test ${PROJECT_SOURCE_DIR}/lib/libSDL2.dll.a)

This is how my demo CMakeList.txt looks(commented out the static linking line for reference)

With dynamic libraries, you don’t need to manually link their dependencies because they are handled by the dll itself. The original poster’s intention was to use a static library.
Anyway, what you’re doing is kinda weird - with CMake you should use the SDL2 package, not link everything by hand…

Hi All :slight_smile:

I share my result because I think it may help other people in the future, this is my set-up for using SDL2 on Win32 with CMake (actually it uses the file named CMakeLists.txt for project configuration)

this configuration build the project without using the sdl2-config script but it configure the enviroments by setting the SDL2_DIR, SDL2_image_DIR, and SDL2_ttf_DIR variables.

The projct is structured as follow:

  • libs that contains the unzip content from the SDL2, SDL2_image and SDL2_ttf releases
  • src that contains the sources of my project
  • include that contains the includes of my project
cmake_minimum_required(VERSION 3.10)
project(tetris)
set(BUILD_SHARED_LIBS OFF)
set(SDL2_DIR libs/lib/cmake/SDL2)
set(SDL2_image_DIR libs/lib/cmake/SDL2_image)
set(SDL2_ttf_DIR libs/lib/cmake/SDL2_ttf)
set(CMAKE_CXX_STANDARD 17)

# Link statico per runtime GCC
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++ -static")

# Trova le librerie SDL2
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
find_package(SDL2_ttf REQUIRED)

add_executable(tetris
        main.cpp
        src/game_engine.cpp
        src/easy_sdl.cpp
)

target_link_libraries(tetris
        SDL2::SDL2-static
        SDL2_image::SDL2_image-static
        SDL2_ttf::SDL2_ttf-static
)

Best regards,
Stefano