Using SDL2 with CMake

66,416

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()
Share:
66,416
Ovenkoek
Author by

Ovenkoek

Updated on July 09, 2022

Comments

  • Ovenkoek
    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 years
    I've got a Unknown CMake command "find". But I could do it using find_library(SDL) instead.
  • usr1234567
    usr1234567 about 7 years
    @charlesrockbass: Thanks for the hint, it should be find_package.
  • Cubic
    Cubic over 6 years
    SDL is not the same as SDL2, and the default FindSDL.cmake does not look for SDL2.
  • Topilski Alexandr
    Topilski Alexandr almost 4 years
  • emlai
    emlai about 3 years
    This doesn't work with Mingw on Windows. The library directory and file names are different in the SDL2 Mingw package.
  • usr1234567
    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
    Max Klint over 2 years
    Be 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 years
    just to add to this. the name of the config file for find package should be sdl2-config.cmake
  • eri0o
    eri0o about 2 years
    Is there a way to use it but without installing it? I want to fetch it and use it.
  • Tom
    Tom about 2 years
    You 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
    eri0o about 2 years
    Thanks! Those links are useful! :) Last one was exactly what I was looking for! Thank you!
  • Tom
    Tom about 2 years
    Awesome! :D Glad it helped, thanks for letting me know
  • Alexis Wilke
    Alexis Wilke over 1 year
    It's ${SDL2_LIBRARIES} (plural). The singular may work, but that would be fortuitous.