wolfgang ziegler


„make stuff and blog about it“

Using SDL with CMake on Mac OS X

May 2, 2020

I 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 calling set.
  • Use find_package with the new name SDLTTF.
  • Use the correct variable names SDL2TTF_INCLUDE_DIR and SDL2TTF_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})