CMake, SDL(2) and MinGW

From vendor/ I made a symlink to SDL2, which I downloaded to a central location using the SDL2-devel-2.30.10-mingw.zip release.

I want to use CMake because my project now has a lot more header and source files.

I am using the x86_64-w64-mingw32 directory’s bin and include folders. This is the path.

The problem is that there is no CMakeLists.txt here. This is my CMakeLists.txt, adapted from the example given in README_cmake.md in the github docs:

cmake_minimum_required(VERSION 3.10)
project(mygame)

add_subdirectory(vendor/sdl EXCLUDE_FROM_ALL)

add_executable(main src/main.cpp src/eventHandlers.cpp src/drawHelpers.cpp src/geometryHelpers.cpp src/loggingHelpers.cpp src/setupHelpers.cpp)

# SDL2::SDL2main may or may not be available. It is e.g. required by Windows GUI applications
if(TARGET SDL2::SDL2main)
    # It has an implicit dependency on SDL2 functions, so it MUST be added before SDL2::SDL2 (or SDL2::SDL2-static)
    target_link_libraries(main PRIVATE SDL2::SDL2main)
endif()

target_link_libraries(main PRIVATE SDL2::SDL2)

# Use include files from the "include" directory when compiling target "main"
target_include_directories(main PUBLIC include)

I of course get an error when I try to add the vendor/sdl subdirectory because of the missing CMakeLists.txt file

My question is basically what is wrong with this cmake file? If there’s nothing wrong then how can I get the cmakelists.txt into vendor/sdl?

add_subdirectory expects a directory with CMakeLists.txt (usually a source directory). To use prebuild artifact you linked you have to use find_package and set SDL2_DIR variable.

What is the SDL2_DIR variable?

You should set the SDL2_DIR variable like this in your project locations, where CMakeLists.txt is located:

> cmake -G "MinGW Makefiles" -S . -B dist -DSDL2_DIR=path/to/lib/cmake/SDL2

Where:

  • -G "MinGW Makefiles" - MinGW generator of makefiles
  • -S . - source directory, where CMakeLists.txt is located
  • -B dist - build directory
  • -DSDL2_DIR - path to the lib/cmake/SDL2 directory, where SDL2 was unzipped or installed using CMake

You can save this command in the config.bat file in your project location.

Next you should build your project:

> cd dist
> cmake --build .

This is MinGW (GCC 14.2): Releases · skeeto/w64devkit · GitHub It is requires 373 MB on the hard disk.

CMakeLists.txt

# Requires CMake version greater than or equal to the following
cmake_minimum_required(VERSION 3.20)

# We indicate the name of the project and the language used
project(example)

# We write the name of the application. The file app.exe will be created
add_executable(app)

# Specify where the application source files are stored
target_sources(app
PRIVATE
    src/main.c
)

# We search for the library at the specified path in -Dlib_DIR
find_package(SDL3)
target_link_libraries(app PRIVATE SDL3::SDL3)

target_link_options(app PRIVATE -static)

I tried this (modified slightly based on the sdl docs on cmake):

I ran the below cmakelists with:

cmake .. -G "MinGW Makefiles" -DCMAKE_TOOLCHAIN_FILE="cmake-toolchain-mingw64-x86_64.cmake" -DSDL2_DIR="C:\mingw_dev_lib\SDL2-2.30.10\i686-w64-mingw32\lib\cmake\SDL2"

this is my new cmakelists

# Run cmake from build/ with: cmake .. -G "MinGW Makefiles" -DCMAKE_TOOLCHAIN_FILE="cmake-toolchain-mingw64-x86_64.cmake" -DSDL2_DIR="C:\mingw_dev_lib\SDL2-2.30.10\i686-w64-mingw32\lib\cmake\SDL2"

cmake_minimum_required(VERSION 3.10)
project(main)

# This creates the file main.exe using the project sources
file(GLOB_RECURSE SRC src/*.cpp)
add_executable(main ${SRC})

# Use include files from the "include" directory when compiling target
target_include_directories(main PUBLIC include)

# Look for a file called sdl2-config.cmake, might be config by default
find_package(SDL2 REQUIRED)

# this if statement below is from the docs:
# SDL2::SDL2main may or may not be available. It is e.g. required by Windows GUI applications
if(TARGET SDL2::SDL2main)
    # It has an implicit dependency on SDL2 functions, so it MUST be added before SDL2::SDL2 (or SDL2::SDL2-static)
    target_link_libraries(main PRIVATE SDL2::SDL2main)
    target_link_options(main)
endif()

target_link_libraries(main PRIVATE SDL2::SDL2)

but I get an error:

-- The C compiler identification is GNU 13.2.0
-- The CXX compiler identification is GNU 13.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/ucrt64/bin/x86_64-w64-mingw32-gcc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/ucrt64/bin/x86_64-w64-mingw32-g++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
CMake Error at C:/mingw_dev_lib/SDL2-2.30.10/i686-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake:13 (message):
  File or directory
  /tmp/tardir/SDL2-2.30.10/build-mingw/install-i686-w64-mingw32/bin
  referenced by variable SDL2_BINDIR does not exist !
Call Stack (most recent call first):
  C:/mingw_dev_lib/SDL2-2.30.10/i686-w64-mingw32/lib/cmake/SDL2/sdl2-config.cmake:27 (set_and_check)
  CMakeLists.txt:14 (find_package)

It looks like the sdl2-config.cmake thinks that I have unzipped sdl2 into /tmp/tardir which is a linux dir, even though I specified SDL2_DIR.

this is the part of sdl2-config.cmake which I think is causing the problem:

set(exec_prefix "${prefix}")
set(bindir "/tmp/tardir/SDL2-2.30.10/build-mingw/install-x86_64-w64-mingw32/bin")
set(libdir "/tmp/tardir/SDL2-2.30.10/build-mingw/install-x86_64-w64-mingw32/lib")
set(includedir "/tmp/tardir/SDL2-2.30.10/build-mingw/install-x86_64-w64-mingw32/include")

set_and_check(SDL2_PREFIX         "${prefix}")
set_and_check(SDL2_EXEC_PREFIX    "${exec_prefix}")
set_and_check(SDL2_BINDIR         "${bindir}")
set_and_check(SDL2_INCLUDE_DIR    "${includedir}/SDL2")
set_and_check(SDL2_LIBDIR         "${libdir}")
set(SDL2_INCLUDE_DIRS             "${includedir};${SDL2_INCLUDE_DIR}")

would it be okay if I manually changed the bindir, libdir and includedir, or is there a better option?

Could you try this command:

cmake -G "MinGW Makefiles" -S . -B dist -DSDL2_DIR=C:/mingw_dev_lib/SDL2-2.30.10/x86_64-w64-mingw32/lib/cmake/SDL2

It didn’t work, I got the same problem.

Yeah I just manually changed it and it worked, I’m hoping for a better solution though. I’ll leave this thread open for now.