CMake: Building SFML and Game Projects on Linux

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

Image for post
Image for post

Introduction

Tutorial Overview

Image for post
Image for post
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 .
Image for post
Image for post
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
Image for post
Image for post
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 .
Image for post
Image for post
Running Pong locally in the project build tree.
$ cmake --build . --target clean
$ make
Image for post
Image for post
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