How to use SDL2 and SDL_image with cmake
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.
Using SDL2 with CMake
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/
How to link SDL_ttf and SDL_image libraries using cmake in windows?
I found the problem:
In
sdl2-image-lib
andsdl2-ttf-lib
directory there arelibSDL2_image.dll.a
andlibSDL2_ttf.dll.a
binary files that must be linked instead oflibSDL2_image.a
andlibSDL2_ttf.a
files.dll files must be copied to the directory where the EXE file is located. the dll files are in bin folders of the library.
The libraries which I used for my project:
https://github.com/satayyeb/sdl2-libraries
and the modified CMakeLists.txt:
set(SOURCE src/main.c)
set(PROJECT_NAME island_soldier)
cmake_minimum_required(VERSION 3.19)
project(${PROJECT_NAME} C)
set(CMAKE_C_STANDARD 11)
set(SDL2_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sdl2/sdl2-include")
set(SDL2_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sdl2/sdl2-lib")
set(SDL2_GFX_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sdl2/sdl2-gfx-include")
set(SDL2_GFX_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sdl2/sdl2-gfx-lib")
set(SDL2_IMAGE_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sdl2/sdl2-image-include")
set(SDL2_IMAGE_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sdl2/sdl2-image-lib")
set(SDL2_TTF_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sdl2/sdl2-ttf-include")
set(SDL2_TTF_LIB_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sdl2/sdl2-ttf-lib")
set(SDL2_FLAGS "-mwindows -Wl,--no-undefined -static-libgcc")
add_library(SDL2 STATIC IMPORTED)
add_library(SDL2main STATIC IMPORTED)
add_library(SDL2_GFX STATIC IMPORTED)
add_library(SDL2_IMAGE_DLL STATIC IMPORTED)
add_library(SDL2_TTF_DLL STATIC IMPORTED)
set_property(TARGET SDL2 PROPERTY IMPORTED_LOCATION "${SDL2_LIB_DIR}/libSDL2.a")
set_property(TARGET SDL2main PROPERTY IMPORTED_LOCATION "${SDL2_LIB_DIR}/libSDL2main.a")
set_property(TARGET SDL2_GFX PROPERTY IMPORTED_LOCATION "${SDL2_GFX_LIB_DIR}/libsdl-gfx.a")
set_property(TARGET SDL2_IMAGE_DLL PROPERTY IMPORTED_LOCATION "${SDL2_IMAGE_LIB_DIR}/libSDL2_image.dll.a")
set_property(TARGET SDL2_TTF_DLL PROPERTY IMPORTED_LOCATION "${SDL2_TTF_LIB_DIR}/libSDL2_ttf.dll.a")
set(SDL2_LIBS mingw32 SDL2 SDL2main SDL2_GFX SDL2_TTF_DLL SDL2_IMAGE_DLL m dinput8 dxguid dxerr8 user32 gdi32 winmm imm32 ole32 oleaut32 shell32 version uuid)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${SDL2_FLAGS}")
file(GLOB_RECURSE SOURCE "src/*.c" "src/*.h")
IF(WIN32)
SET(GUI_TYPE WIN32)
ENDIF(WIN32)
IF (APPLE)
SET(GUI_TYPE MACOSX_BUNDLE)
ENDIF (APPLE)
add_executable("${PROJECT_NAME}" ${GUI_TYPE} "${SOURCE}")
include_directories(${SDL2_INCLUDE_DIR} ${SDL2_GFX_INCLUDE_DIR} ${SDL2_IMAGE_INCLUDE_DIR} ${SDL2_TTF_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME} ${SDL2_LIBS})
Using SDL2 with SDL2_image on OSX 10.11 (CMake 3.3 within CLion 1.1)
I feel stupid... My CMakeLists.txt file is correct except i needed to add the following
target_link_libraries(Cavestory ${SDL2_LIBRARY} ${SDL2_IMAGE_LIBRARY})
instead of
target_link_libraries(Cavestory SDL2 SDL2_image)
This fixes the SDL linking issue from SDL_image.h; However, after updating to El Capitan, I can no longer reference SDL via #include "SDL2/SDL.h"
and must use #include "SDL.h"
-- while this is preferred, I'd like to know why/how this changed between OSX 10.10 and OSX 10.11.
How to build SDL_Image from FetchContent?
There are two problems with your CMake file:
GIT_TAG release-2.0.5
If you look at the SDL_Image repo at that tag, there's no CMakeLists.txt
file. That is indeed the most recent tag, though. But fortunately, according to the docs you can use a git SHA for GIT_TAG
. With the most recent git SHA at the time of writing, that would look like this:
GIT_TAG 97405e74e952f51b16c315ed5715b6b9de5a8a50
The other error is that SDL2_image-static
doesn't exist. You need to change that in your set(SDL_LIBRARIES ...)
line to just SDL2_image
.
With those two changes, I'm able to #include SDL_Image.h
.
How to link SDL2 in CMake?
To link a library (shared/static) in cmake you can use the target_link_libraries command:
target_link_libraries(<target> ... <item>... ...)
According to the documentation:
<target>
must have been created by a command such asadd_executable()
oradd_library()
So first of all we need to find the SDL library, for that we will use the command:
find_package(SDL2 REQUIRED)
to make it's include directories available to you, use the command:
include_directories(${SDL2_INCLUDE_DIRS})
And finally to link SDL2, you need to do:
target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARIES})
or alternatively:
target_link_libraries(${PROJECT_NAME} PRIVATE SDL2::SDL2)
PRIVATE
, means that ${PROJECT_NAME}
uses SDL2
in its implementation, but SDL2
is not used in any part of ${PROJECT_NAME}
's public API. More here
Here ${PROJECT_NAME}
is the <target>
, and all the rest that follow are names of libraries.
Final Result
# Set the minimum version of CMake that can be used
# To find the cmake version run
# $ cmake --version
cmake_minimum_required(VERSION 3.5)
# Set the project name
project (sdl)
find_package(SDL2 REQUIRED)
# Create a sources variable with a link to all cpp files to compile
set(SOURCES
src/main.cpp
)
# Add an executable with the above sources
add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(sdl ${SDL2_LIBRARIES})
# Set the directories that should be included in the build command for this target
include_directories(SDL2Test ${SDL2_INCLUDE_DIRS})
Refs:
- https://cmake.org/cmake/help/latest/command
- https://cmake.org/pipermail/cmake/2016-May/063400.html
Building SDL2_image as a CMake external project
Looks like you need to link some libraries like m
and dl
. It can be fixed by providing
custom sdl2-config
file. Copy sdl2-config
from extracted archive and substitute --libs
result:
--libs)
echo -L${exec_prefix}/lib -Wl,-rpath,${libdir} -pthread -lSDL2 -lm -ldl
;;
Note that order is important (that's why just modifying LIBS not works for me).
Now this file can be used in your ExternalProject_Add
command instead of SDL2_CONFIG=${SDL2_BIN}/sdl2-config
:
...
... CFLAGS=-I${SDL2_SRC}/include SDL2_CONFIG=${CMAKE_CURRENT_LIST_DIR}/sdl2-config <SOURCE_DIR>/configure
...
Related Topics
Two String Literals Have the Same Pointer Value
Why Does Streaming a Char Pointer to Cout Not Print an Address
Passing a Std::Array of Unknown Size to a Function
Writing Universal Memoization Function in C++11
Difference Between Std::System_Clock and Std::Steady_Clock
C++: Simple Return Value from Std::Thread
Long Long Int VS. Long Int VS. Int64_T in C++
What Range of Values Can Integer Types Store in C++
Differencebetween Std::Array and Std::Vector? When Do You Use One Over Other
How Much Is the Overhead of Smart Pointers Compared to Normal Pointers in C++
What Is the Purpose of Using -Pedantic in the Gcc/G++ Compiler
What's the Difference Between "Static" and "Dynamic" Schedule in Openmp
Remove C and C++ Comments Using Python
How to Implement Multithread Safe Singleton in C++11 Without Using <Mutex>