Using SDL with CMake on Mac OS X
May 2, 2020I was experimenting with CMake and SDL and was looking for the recommended way to add SDL to the project. Most of the instructions I found looked like this.
Failing
My CMakeLists.txt
looked something like this.
##
## Warning: This code did not work for me.
## Don't copy it.
## Keep reading.
##
find_library(SDL2_LIBRARY NAME SDL2)
add_executable(MyProject main.cpp)
include_directories(age ${SDL2_INCLUDE_DIR})
target_link_libraries(MyProject ${SDL2_LIBRARY})
Running cmake
resulted in an error message about SDL2_INCLUDE_DIR
, so obviously the find_library
call had succeeded but the variable value wasn't set regardless.
$ cmake .
-- Configuring done
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
SDL2_INCLUDE_DIR
...
Adding Debug Output
So I added some logging messages about SDL2_INCLUDE_DIR
and SDL2_LIBRARY
as well.
find_library(SDL2_LIBRARY NAME SDL2)
# Add log messages
message ([STATUS] "SDL2_INCLUDE_DIR" ${SDL2_INCLUDE_DIR})
message ([STATUS] "SDL2_LIBRARY" ${SDL2_LIBRARY})
The output immediately showed why this could not have worked.
$ cmake .
SDL2_INCLUDE_DIR: SDL2_INCLUDE_DIR-NOTFOUND
SDL2_LIBRARY: SDL2_LIBRARY-NOTFOUND
CMake Error at src/ui/CMakeLists.txt:18 (target_include_directories):
target_include_directories called with invalid arguments
Digging Deeper
So I took a look into the cmake module code that would run for the find_library
call.
A simple locate
command narrowed this down:
$ locate SDL2
...
/usr/local/Cellar/sdl2/2.0.12_1/lib/cmake/SDL2/sdl2-config.cmake
...
The first glance at this file made it obvious that the variables I had been using were simply wrong (probably changed over time).
Instead of SDL2_INCLUDE_DIR
SDL2_INCLUDE_DIRS
must be used.
Instead of SDL2_LIBRARY
SDL2_LIBRARIES
must be used.
Making it Work
From there it was easy and updating the CMakeLists.txt
file to use the correct variable names did the trick.
find_library(SDL2_LIBRARY NAME SDL2)
add_executable(MyProject main.cpp)
include_directories(MyProject ${SDL2_INCLUDE_DIRS})
target_link_libraries(MyProject ${SDL2_LIBRARIES})
Bonus: Adding SDL_TTF
This was supposed to be as simple as adding this line to CMakeLists.txt
find_package(SDL_ttf REQUIRED)
Of course, it resulted in an immediate error.
$ cmake .
CMake Error at /usr/local/Cellar/cmake/3.17.1/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:164 (message):
Could NOT find SDL_ttf (missing: SDL_TTF_LIBRARIES SDL_TTF_INCLUDE_DIRS)
Searching on the internet, I quickly found a solution to this problem.
Apparently this is some issue about SDL
and SDL2
and someone already created a custom cmake module for that.
These steps resolved that problem for me:
- Download the FindSDL2TTF.cmake file.
- Copy it into a
cmake
folder in my project. - Add this folder to the
CMAKE_MODULE_PATH
by callingset
. - Use
find_package
with the new nameSDLTTF
. - Use the correct variable names
SDL2TTF_INCLUDE_DIR
andSDL2TTF_LIBRARY
.
Here's how that looks in CMakeLists.txt
.
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
find_package(SDLTTF REQUIRED)
include_directories(${SDL2TTF_INCLUDE_DIR})
add_executable(MyProject ${SOURCES})
target_link_libraries(MyProject ${SDL2TTF_LIBRARY})