[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.