Using SDL2 with CMake
Solution 1
Don't set the path to SDL2 by hand. Use the proper find command which uses FindSDL. Should look like:
find_file(SDL2_INCLUDE_DIR NAME SDL.h HINTS SDL2)
find_library(SDL2_LIBRARY NAME SDL2)
add_executable(ChickenShooter main.cpp)
target_include_directories(ChickenShooter ${SDL2_INCLUDE_DIR})
target_link_libraries(ChickenShooter ${SDL2_LIBRARY})
If SDL2 is not found, you have to add the path to SDL2 to CMAKE_PREFIX_PATH
, that's the place where CMake looks for installed software.
If you can use Pkg-config, its use might be easier, see How to use SDL2 and SDL_image with cmake
If you feel more comfortable to use a FindSDL2.cmake file similar to FindSDL.cmake provided by CMake, see https://brendanwhitfield.wordpress.com/2015/02/26/using-cmake-with-sdl2/
Solution 2
This blog post shows how you can do it: Using SDL2 with CMake
On Linux you can use a recent CMake (e.g. version 3.7) and using SDL2 works out of the box.
cmake_minimum_required(VERSION 3.7)
project(SDL2Test)
find_package(SDL2 REQUIRED)
include_directories(SDL2Test ${SDL2_INCLUDE_DIRS})
add_executable(SDL2Test Main.cpp)
target_link_libraries(SDL2Test ${SDL2_LIBRARIES})
Under Windows you can download the SDL2 development package, extract it somewhere and then create a sdl-config.cmake
file in the extracted location with the following content:
set(SDL2_INCLUDE_DIRS "${CMAKE_CURRENT_LIST_DIR}/include")
# Support both 32 and 64 bit builds
if (${CMAKE_SIZEOF_VOID_P} MATCHES 8)
set(SDL2_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/x64/SDL2.lib;${CMAKE_CURRENT_LIST_DIR}/lib/x64/SDL2main.lib")
else ()
set(SDL2_LIBRARIES "${CMAKE_CURRENT_LIST_DIR}/lib/x86/SDL2.lib;${CMAKE_CURRENT_LIST_DIR}/lib/x86/SDL2main.lib")
endif ()
string(STRIP "${SDL2_LIBRARIES}" SDL2_LIBRARIES)
When you now configure inside the CMake-GUI application there will be a SDL2_DIR
variable. You have to point it to the SDL2 directory where you extracted the dev package and reconfigure then everything should work.
You can then include SDL2 headers by just writing #include "SDL.h"
.
Solution 3
You can also pull in the SDL source repository as a submodule and build/link it statically along with your main program via add_subdirectory()
and target_link_libraries()
:
cmake_minimum_required( VERSION 3.7.0 )
project( sdl2-demo )
set( SDL_STATIC ON CACHE BOOL "" FORCE )
set( SDL_SHARED OFF CACHE BOOL "" FORCE )
add_subdirectory( external/sdl )
add_executable(
sdl2-demo
"src/main.cpp"
)
target_link_libraries( sdl2-demo SDL2main SDL2-static )
(At least as of the release-2.0.9
tag, possibly earlier.)
Solution 4
cmake_minimum_required(VERSION 2.8.4)
project(ChickenShooter)
set(SDL2_INCLUDE_DIR C:/SDL/SDL2-2.0.3/include/SDL2)
set(SDL2_LIB_DIR C:/SDL/SDL2-2.0.3/lib/x64)
include_directories(${SDL2_INCLUDE_DIR})
link_directories(${SDL2_LIB_DIR})
set(SOURCE_FILES main.cpp)
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} SDL2main SDL2)
Solution 5
I recently discovered the latest version of SDL2 (version 2.0.12) now comes with all the required CMake config/install scripts, so there's no need to use FindSDL anymore.
I downloaded the SDL source from https://www.libsdl.org/download-2.0.php then from the root folder ran...
cmake -S . -B build/debug -G Ninja -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_BUILD_TYPE=Debug
cmake --build build/debug --target install
This will build and install the debug version of the library, you can then also run...
cmake -S . -B build/release -G Ninja -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_BUILD_TYPE=Release
cmake --build build/release --target install
Which will build and install the release version of the library (and because the SDL CMake script uses DEBUG_POSTFIX the release version of the library won't overwrite the debug one as the debug versions all have 'd' appended to their name).
In your CMakeLists.txt file you can then simply do this:
find_package(SDL2 REQUIRED)
add_executable(${PROJECT_NAME} ...)
target_link_libraries(
${PROJECT_NAME} PRIVATE
SDL2::SDL2
SDL2::SDL2main
You'll need to tell your application where to find the SDL install folder if you used a custom location as I've done in the example. To do this from the root folder of your app run:
cmake -S . -B build/debug -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=</absolute/path/to/install/dir>
cmake --build build/debug
Note: You can use
$(pwd)
(*nix/macOS) or%cd%
(Windows) to create a hybrid relative path which can be very useful.
You can omit both DCMAKE_INSTALL_PREFIX
and DCMAKE_PREFIX_PATH
if you want to install SDL to the default system location.
In the examples I've opted to use the Ninja generator as it is consistent across macOS/Windows - it can be used with MSVC/Visual Studio, just make sure you run this (path may differ slightly depending on year/version) to add Ninja to your path.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat
Update:
One other thing I remembered which is useful on Windows is the ability to copy the SDL .dll file into the application binary directory, this can be achieved like so:
if (WIN32)
# copy the .dll file to the same folder as the executable
add_custom_command(
TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:SDL2::SDL2>
$<TARGET_FILE_DIR:${PROJECT_NAME}>
VERBATIM)
endif()

Ovenkoek
Updated on July 09, 2022Comments
-
Ovenkoek 5 months
I'm trying to use CLion to create a SDL2 project. The problem is that the SDL headers can't be found when using #include's.
My CMakeLists.txt file:
cmake_minimum_required(VERSION 2.8.4) project(ChickenShooter) set(SDL2_INCLUDE_DIR C:/SDL/SDL2-2.0.3/include) set(SDL2_LIBRARY C:/SDL/SDL2-2.0.3/lib/x64) include_directories(${SDL2_INCLUDE_DIR}) set(SOURCE_FILES main.cpp) add_executable(ChickenShooter ${SOURCE_FILES}) target_link_libraries(ChickenShooter ${SDL2_LIBRARY})
My test main.cpp:
#include <iostream> #include "SDL.h" /* This one can't be found */ int main(){ if (SDL_Init(SDL_INIT_VIDEO) != 0){ std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl; return 1; } SDL_Quit(); return 0; }
Thank you for any help you could give me.
Edit: I'm using Windows and CLion is configured to use cygwin64.
-
Charles about 7 yearsI've got a
Unknown CMake command "find"
. But I could do it usingfind_library(SDL)
instead. -
usr1234567 about 7 years@charlesrockbass: Thanks for the hint, it should be find_package.
-
Cubic over 6 yearsSDL is not the same as SDL2, and the default FindSDL.cmake does not look for SDL2.
-
Topilski Alexandr almost 4 yearsgithub.com/fastogt/fastoplayer/blob/master/src/… crossplatfrom
-
emlai about 3 yearsThis doesn't work with Mingw on Windows. The library directory and file names are different in the SDL2 Mingw package.
-
usr1234567 over 2 years@FRR Great question, but kind of unrelated to this answer. Please open a question, and I'll happily answer it.
-
Max Klint over 2 yearsBe aware that this cmake script can fail if the path to project contains spaces (at least on Mac OS). Other than that, indeed it is an easy way to statically link to SDL2.
-
Groshh over 2 yearsjust to add to this. the name of the config file for find package should be sdl2-config.cmake
-
eri0o about 2 yearsIs there a way to use it but without installing it? I want to fetch it and use it.
-
Tom about 2 yearsYou could use FetchContent instead of you prefer - it should work much the same. There's some info about it here you might find useful - github.com/pr0g/cmake-examples/tree/main/examples/more/…. Here's an example of using ExternalProject_Add to add SDL (essentially automates the above steps - github.com/pr0g/sdl-bgfx-imgui-starter/blob/main/third-party/…)
-
eri0o about 2 yearsThanks! Those links are useful! :) Last one was exactly what I was looking for! Thank you!
-
Tom about 2 yearsAwesome! :D Glad it helped, thanks for letting me know
-
Alexis Wilke over 1 yearIt's
${SDL2_LIBRARIES}
(plural). The singular may work, but that would be fortuitous.