[Latest version of these instructions can be found at the SFML Wiki]
CMake allows your project to be built in various environments, including command-line make, Code::Blocks project files, Eclipse project files, etc. It's used in SFML 2.0.
In this tutorial we'll write a simple CMake configuration file with centralized version numbering, and see how to integrate SFML in it.
The source files
First, create a cmake_modules directory and copy FindSFML.cmake in it. FindXXXX is automatically searched by CMake's find_package command.
Then create a main.cpp, for instance:
#include "config.h" #include <iostream> #include <SFML/Window.hpp> using namespace std; int main(int argc, char* argv[]) { cout << "Version " << myproject_VERSION_MAJOR << "." << myproject_VERSION_MINOR << endl; sf::Window screen(sf::VideoMode(800, 600), "myproject"); bool running = true; while (running) { screen.Display(); } }
We use a config.h file that is built by CMake, let's also create a config.h.in file:
#define myproject_VERSION_MAJOR @myproject_VERSION_MAJOR@ #define myproject_VERSION_MINOR @myproject_VERSION_MINOR@
And place your project license (such as the GNU GPL) in a file named COPYING.
CMake configuration
Let's describe our project configuration in the CMakeLists.txt file:
cmake_minimum_required(VERSION 2.6) project(myproject) # Set version information in a config.h file set(myproject_VERSION_MAJOR 1) set(myproject_VERSION_MINOR 0) configure_file( "${PROJECT_SOURCE_DIR}/config.h.in" "${PROJECT_BINARY_DIR}/config.h" ) include_directories("${PROJECT_BINARY_DIR}") # Define sources and executable set(EXECUTABLE_NAME "myproject") add_executable(${EXECUTABLE_NAME} main.cpp) # Detect and add SFML set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) find_package(SFML 1.6 REQUIRED system window graphics network audio) target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES}) # Install target install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin) # CPack packaging include(InstallRequiredSystemLibraries) set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING") set(CPACK_PACKAGE_VERSION_MAJOR "${myproject_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${myproject_VERSION_MINOR}") include(CPack)
The interesting part is:
# Detect and add SFML set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) find_package(SFML 1.6 REQUIRED system window graphics network audio) target_link_libraries(${EXECUTABLE_NAME} ${SFML_LIBRARIES})
- First we specify where we stored the FindSFML.cmake module.
- Then we request CMake to look for it in the system, and search for the specified modules (here I specified them all).
- Last, we tell CMake to link our executable with the SFML libraries that it just found.
Compilation
To build with Make and the GCC compiler on the command-line:
cd build/ # a separate directory so we can easily remove all the CMake work files cmake .. # generate Makefile's make
To create Code::Blocks project files:
cmake .. -G "CodeBlocks - Unix Makefiles"
and open project.cbp with Code::Blocks.
Installation
CMake supports the classic:
make install
It also supports DESTDIR, useful in packaging:
make install DESTDIR=`pwd`/myworkdir
You can also define CMAKE_INSTALL_PREFIX when invoking cmake to change the default install path (/usr/local under Unix). DESTDIR would still override this setting.
Packaging
You then can use cpack to make a project release:
# Binary package: cpack -C CPackConfig.cmake # Source package: cpack -C CPackSourceConfig.cmake
You will get a nice myproject-1.0.tar.gz, among others.
Further information
- CMake has built-in help, for instance:
$ cmake --help-variable CMAKE_SOURCE_DIR cmake version 2.8.5 CMAKE_SOURCE_DIR The path to the top level of the source tree. This is the full path to the top level of the current CMake source tree. For an in-source build, this would be the same as CMAKE_BINARY_DIR.