How to use SDL2 and SDL_image with cmake

63,285

Solution 1

I think that the following will work, as it finds the libraries on my ubuntu system and the example function you provided can link:

project(shooter-cmake2)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_executable(${PROJECT_NAME} src/test.cpp)
INCLUDE(FindPkgConfig)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARIES})

If cmake is executed with --debug-output it outputs:

-- Found PkgConfig: /usr/bin/pkg-config (found version "0.26") 
Called from: [2]    /usr/share/cmake-2.8/Modules/FindPkgConfig.cmake
            [1] $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
-- checking for one of the modules 'sdl2'
Called from: [1]    $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt
-- checking for one of the modules 'SDL2_image>=2.0.0'
Called from: [1]    $USER/stack-overflow/cmake-sdl2-image/CMakeLists.txt

This made me check the contents of

/usr/lib/x86_64-linux-gnu/pkgconfig/sdl2.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/SDL2_image.pc

I noticed that SDL2_image.pc contains Name: SDL2_image which I assumed should match the third parameter to PKG_SEARCH_MODULE for this library.

Solution 2

There are two blog posts about this here:

Using SDL2 with CMake

Using SDL2_image with CMake

Basically you need a FindSDL2.cmake and FindSDL2_image.cmake module. They can be based of the ones that work for SDL 1.2 which are included in CMake already. Using these Find modules will also work on Windows.

If you are on Linux and only need SDL2 you don't even need the FindSDL2.cmake as the following already works:

cmake_minimum_required(VERSION 3.7)
project(SDL2Test)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
add_executable(SDL2Test Main.cpp)
target_link_libraries(SDL2Test ${SDL2_LIBRARIES})

Solution 3

I was having trouble with these answers, I think cmake changed the way to import targets. Following @trenki blog post I needed to change my CMakeLists.txt to:

project(SDL2Test)
find_package(SDL2 REQUIRED COMPONENTS SDL2::SDL2)
add_executable(SDL2Test main.cpp)
target_link_libraries(SDL2Test SDL2::SDL2)

Currently this works out of the box on Arch Linux.

Solution 4

I introduced a modern and portable approach for linking to the SDL2, SDL2_image. These SDL2 CMake modules let you build an SDL2 & SDL2_image project as follows :

list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
find_package(SDL2 REQUIRED)
find_package(SDL2_image REQUIRED)
target_link_libraries(${PROJECT_NAME} SDL2::Main SDL2::Image)

You should just clone the repo in your project:

git clone https://github.com/aminosbh/sdl2-cmake-modules cmake/sdl2

Note: If CMake didn't find the SDL2/SDL2_image libraries (in Windows), we can specify the CMake options SDL2_PATH and SDL2_IMAGE_PATH as follows:

cmake .. -DSDL2_PATH="/path/to/sdl2" -DSDL2_IMAGE_PATH="/path/to/sdl2-image"

It supports also other related libraries : SDL2_ttf, SDL2_net, SDL2_mixer and SDL2_gfx. For more details, please read the README.md file.

You can find a list of examples/samples and projects that uses these modules here : https://github.com/aminosbh/sdl-samples-and-projects

Share:
63,285
Carl Lemaire
Author by

Carl Lemaire

I study imagery and digital media at bachelor level at the Université de Sherbrooke. The degree is called "Sciences de l'image et des médias numériques".

Updated on February 20, 2020

Comments

  • Carl Lemaire
    Carl Lemaire over 3 years

    I'm looking for the simplest way to compile a c++ program using SDL2 and SDL_image with cmake.

    Here is my best attempt, after hours of searching:

    CMakeLists.txt

    project(shooter-cmake2)
    cmake_minimum_required(VERSION 2.8)
    set(SOURCES
    shooter.cpp
    classes.cpp
    utils.cpp
    )
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
    add_executable(${PROJECT_NAME} ${SOURCES})
    INCLUDE(FindPkgConfig)
    PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
    PKG_SEARCH_MODULE(SDL2_image REQUIRED sdl2_image)
    INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIR})
    TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${SDL2_LIBRARIES} ${SDL2IMAGE_LIBRARY})
    

    I get these errors:

    In function `loadTexture(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, SDL_Renderer*)':
    undefined reference to `IMG_LoadTexture'
    collect2: ld returned 1 exit status
    

    Here is the function call:

    #include "SDL.h"
    #include "SDL_image.h"
    SDL_Texture* loadTexture(const std::string &file, SDL_Renderer *ren){
        SDL_Texture *texture = IMG_LoadTexture(ren, file.c_str());
        texture != nullptr or die("LoadTexture");
        return texture;
    }
    

    I am desperate. Please help me! Thanks! :)

  • Carl Lemaire
    Carl Lemaire about 9 years
    Thanks, that worked like a charm! Where did you find how to do this? What reference?
  • wojciii
    wojciii about 9 years
    I did not use any reference just what I could read from the source of the module you use and what I know about how .pc files work .. I updated the answer with additional info. :)
  • Carl Lemaire
    Carl Lemaire about 9 years
    Thanks for the edit! But how has --debug-output helped you? I'm just trying to understand how you worked it out.
  • wojciii
    wojciii about 9 years
    The debug output told me that pkg was used and that one library configured used one pkg file was working while another was not. That narrows it down.
  • emlai
    emlai over 7 years
    Since CMake 3.1, set(CMAKE_CXX_STANDARD yy) is preferred over modifying CMAKE_CXX_FLAGS.
  • wojciii
    wojciii over 7 years
    You should definitely improve the answer. ;)
  • sinner
    sinner almost 7 years
    That was awesome! Thanks!
  • JusticeJuice
    JusticeJuice over 6 years
    In my case the modules name has to be SDL2_IMAGE instead of SDL2IMAGE.
  • user2023370
    user2023370 almost 5 years
    How does this work on Linux? (I have seen that it does.) Is there a FindSDL2.cmake installed with CMake on Linux?
  • user2023370
    user2023370 almost 5 years
    Woah, so current Ubuntu 18.04 fails to locate SDL2_image with find_package, but this works!? I'm really trying (this time) not to use explicit paths, and found that on some systems I have to use find_package in "config" mode - but now this? I read then that FindPkgConfig is somehow "external" to CMake...but if it does find the elusive SDL2_image, maybe it will find all my other libraries too...is this the future or the past...one ring to rule them all...it'll only take a few more hours to check...
  • user2023370
    user2023370 almost 5 years
    I also saw some similar double colon stuff, but couldn't get it to work with SDL2_image. It all depends on whether different flavours of ad-hoc "find" configuration files are present on your system. CMake does demand your patience. Can we not all just agree to put our files in the same place :)
  • user2023370
    user2023370 almost 5 years
    The module list for current CMake (v3.12) here doesn't appear to include SDL2 support, so how does this work?
  • trenki
    trenki over 4 years
    SDL2 under linux includes a CMake config file. That way it works without a FindSDL2 module.