CMake: Building SFML and Game Projects on Linux

A tutorial on how to build and install game projects using CMake and SFML

Introduction

Tutorial Overview

Running the Pong game.

Source Files

$ git clone https://github.com/danebulat/cmake-sfml-demo.git

1. Building and Installing SFML

$ pacman -Ss sfml
-| community/sfml 2.5.1-2
A simple, fast, cross-platform, and object-oriented
multimedia API

Installing SFML Dependencies

An overview of SFML dependencies.
# Use your package manager to identify SFML dependencies
$ pacman -Si sfml
-| Depends On : libsndfile libxrandr openal glew freetype2
libx11
$ sudo pacman -S mesa libsndfile libxrandr openal glew freetype2 
libx11
$ sudo pacman -S doxygen graphviz

Downloading SFML

$ git clone https://github.com/SFML/SFML.git
$ du -hs SFML/
-| 159M SFML/
Important directories and files in the SFML project repository.

Building SFML

# Enter SFML repository
$ cd SFML/
# Create and enter a build directory
$ mkdir build && cd build
$ cmake ..
$ cmake --help | less
-| Generators
...
* Unix Makefiles = Generates standard UNIX makefiles.
$ ccmake .
Inspecting and setting options in the SFML cache.
Important CMake cache settings in the SFML build configuration.
$ make
$ sudo make install
Default install locations for SFML artifacts.

2. Creating a Boilerplate SFML Project

> Boilerplate/
---> CMakelists.txt
---> config.h.in
---> main.cpp

CMake Configuration File

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(SFMLBoilerplate VERSION 0.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug
CACHE STRING "Choose the type of build (Debug or Release)" FORCE)
endif()
configure_file(config.h.in config.h)
find_package(SFML 2.5 
COMPONENTS
system window graphics network audio REQUIRED)
add_executable(SFMLBoilerplate main.cpp)
target_include_directories(SFMLBoilerplate
PRIVATE "${PROJECT_BINARY_DIR}")
target_link_libraries(SFMLBoilerplate sfml-graphics)
install(TARGETS SFMLBoilerplate DESTINATION bin)

Building and Running the Boilerplate Project

$ cd Boilerplate
$ mkdir build && cd build
$ cmake ..
$ ccmake .
$ make
$ ./SFMLBoilerplate
Building and running the boilerplate application.

3. Building and Installing a Pong Game

> Pong/
---> CMakeLists.txt
---> content/
---> background.png
---> bip.wav
---> sansation.ttf
---> include/
---> Ball.h
---> Bat.h
---> config.h.in
---> src/
---> Ball.cpp
---> Bat.cpp
---> main.cpp

CMake Configuration File

option(USE_INSTALL_RESOURCE_PATH 
"Set resource path to install location" OFF)
if(NOT USE_INSTALL_RESOURCE_PATH)
set(RESOURCE_PATH "${PROJECT_SOURCE_DIR}/content/")
else()
set(RESOURCE_PATH
"${CMAKE_INSTALL_PREFIX}/share/${CMAKE_PROJECT_NAME}/content/")
endif()
std::string source_dir = RESOURCE_PATH; // ... Load font
sf::Font font;
if (!font.loadFromFile(source_dir + "sansation.TTF"))
return EXIT_FAILURE;
// ... Load texture
sf::Texture texture;
if (!texture.loadFromFile(source_dir + "background.png"))
return EXIT_FAILURE;
// ... Load sound buffer
sf::SoundBuffer buffer;
if (!buffer.loadFromFile(source_dir + "bip.wav"))
return EXIT_FAILURE;
find_package(SFML 2.5 
COMPONENTS system window graphics audio REQUIRED)
add_executable(Pong src/main.cpp src/Ball.cpp src/Bat.cpp)
target_include_directories(Pong 
PRIVATE
"${PROJECT_BINARY_DIR}"
"${CMAKE_CURRENT_SOURCE_DIR}/include")
# Using INSTALL_RPATH_USE_LINK_PATH
set_target_properties(Pong
PROPERTIES
INSTALL_RPATH_USE_LINK_PATH TRUE)

# Using INSTALL_RPATH
set_target_properties(Pong
PROPERTIES
INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
target_link_libraries(Pong sfml-graphics sfml-audio)
# Copy Pong to /usr/local/bin
install(TARGETS Pong DESTINATION bin)

# Copy content/ to /usr/local/share/Pong
install(DIRECTORY content
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/${CMAKE_PROJECT_NAME}")

Building and Installing Pong

$ cd Pong 
$ mkdir build && cd build
$ cmake ..
$ cmake --build .
Running Pong locally in the project build tree.
$ cmake --build . --target clean
$ make
Configuring a release version of Pong and then building it.
$ sudo make install
[100%] Built target Pong
Install the project...
-- Install configuration: "Release"
-- Installing: /usr/local/bin/Pong
-- Set runtime path of "/usr/local/bin/Pong" to "/usr/local/lib"
-- Installing: /usr/local/share/Pong/content
-- Installing: /usr/local/share/Pong/content/bip.wav
-- Installing: /usr/local/share/Pong/content/background.png
-- Installing: /usr/local/share/Pong/content/sansation.ttf

In Conclusion

Related Articles

MSc. Programmer and fan of open source software.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store