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:
With the compiled version of SDL2-2.0.9 with MinGW-w64 in Windows, the following configuration works for me:
find_package(SDL2 REQUIRED)
add_executable(sdl-test ${SOURCES})
target_link_libraries(sdl-test
mingw32
SDL2::SDL2main
SDL2::SDL2
)
A longer explanation
By reading SDL2Targets.cmake
file, I've learned that SDL2 is providing several targets:
SDL2::SDL2main
(lib/libSDL2main.a
)SDL2::SDL2
(lib/libSDL2.dll.a
)SDL2::SDL2-static
(lib/libSDL2-static.a
)Each of them has INTERFACE_INCLUDE_DIRECTORIES
defined, which means we don't need to manually specify include_directories
for SDL2.
But by only adding SDL2::SDL2main
and SDL2::SDL2
as target_link_libraries
is not enough. The g++ compiler might be complaining about "undefined reference to `WinMain'".
By inspecting the compiler options, I found that the SDL2 libraries are added before -lmingw32
option. In order to make the -lmingw32
option comes before SDL2 libraries, we have to also specify mingw32
as the first target_link_libraries
. Which will make this configuration working.
The command that I have used for building it is:
$ mkdir build && cd build && cmake .. -G"MinGW Makefiles" && cmake --build .
The only small problem here is in the finally generated compiler options, the -lmingw32
option is duplicated. But since it doesn't affect the linking process, I've ignored it for now.
Highlighting the steps of how I was able to eventually accomplish this using the FindSDL2.cmake module:
SET(SDL2_SEARCH_PATHS
line in the FindSDL2.cmake and add your copied development directory for SDL2 as a new line: "/Program Files (x86)/SDL2-2.0.9" # Windows
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
After this, running CMake worked for me. I'm including the rest of my CMakeLists just in case it further clarifies anything I may have left out:
cmake_minimum_required(VERSION 2.8.4)
project(Test_Project)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# includes cmake/FindSDL2.cmake
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
set(SOURCE_FILES src/main.cpp src/test.cpp)
add_executable(test ${SOURCE_FILES})
# The two lines below have been removed to run on my Windows machine
#INCLUDE(FindPkgConfig)
#PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
find_package(SDL2 REQUIRED)
INCLUDE_DIRECTORIES(${SDL2_INCLUDE_DIR})
TARGET_LINK_LIBRARIES(chip8 ${SDL2_LIBRARY})
Hope this helps somebody in the near future.
I had the same problem and none of the other solutions worked. But I finally got it working by following this solution : How to properly link libraries with cmake?
In a nutshell, the problem was that the SDL2 library was not linked properly in my CMakeLists.txt. And by writing this into the file, it worked (more explainations in the other thread) :
project (MyProgramExecBlaBla) #not sure whether this should be the same name of the executable, but I always see that "convention" cmake_minimum_required(VERSION 2.8) ADD_LIBRARY(LibsModule file1.cpp file2.cpp ) target_link_libraries(LibsModule -lpthread) target_link_libraries(LibsModule liblapack.a) target_link_libraries(LibsModule -L/home/user/libs/somelibpath/) ADD_EXECUTABLE(MyProgramExecBlaBla main.cpp) target_link_libraries(MyProgramExecBlaBla LibsModule)
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 -G Ninja -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_BUILD_TYPE=Debug
cmake --build build --target install
This will build and install the debug version of the library, you can then also run...
cmake -S . -B build -G Ninja -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_BUILD_TYPE=Release
cmake --build build --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 -G Ninja -DCMAKE_BUILD_TYPE=Debug -DCMAKE_PREFIX_PATH=</absolute/path/to/install/dir>
cmake --build build
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()
You don't seems to have a CMake error whike generating your make file. But I think your problem is, the SDL Header are located in a subfolder named "SDL2".
Change your CMakeLists.txt to include
C:/SDL/SDL2-2.0.3/include/SDL2
Instead of
C:/SDL/SDL2-2.0.3/include
Using the SDL2 CMake module that I developed, you can integrate the SDL2 library easily in a modern and portable approach.
You should just copy the module in cmake/sdl2
(Or just clone the modules repo) in your project:
git clone https://github.com/aminosbh/sdl2-cmake-modules cmake/sdl2
Then add the following lines in your CMakeLists.txt:
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/sdl2)
find_package(SDL2 REQUIRED)
target_link_libraries(${PROJECT_NAME} SDL2::Main)
Note: If CMake didn't find the SDL2 library (in Windows), we can specify the CMake option SDL2_PATH
as follows:
cmake .. -DSDL2_PATH="/path/to/sdl2"
For more details, please read the README.md file.
The SDL2 CMake modules support other related libraries : SDL2_image, SDL2_ttf, SDL2_mixer, SDL2_net and SDL2_gfx.
You can find a list of examples/samples and projects that uses these modules here : https://github.com/aminosbh/sdl-samples-and-projects