Compiling SFML with CMake

Introduction

Well, ok, the title of this tutorial is not completely right. You will not compile SFML with CMake, because CMake is not a compiler. So... what is CMake?

CMake is an open-source meta build system. Instead of building SFML, it builds what builds SFML: Visual studio solutions, Code::Blocks workspaces, Linux makefiles, XCode projects, ... in fact it can generate the makefiles or projects for the OS and compiler of your choice. It is similar to autoconf/automake or premake -- for those who are already familiar with these tools.

CMake is widely used, by well-known projects such as Blender, Boost, KDE, or Ogre. You can read more about CMake on its official website or on the wikipedia page.

So, as you've probably understood, this tutorial is made of two main sections: generating the build files with CMake, and then building SFML with your preferred compiler.

Installing dependencies

SFML depends on a few other libraries, so before starting to compile you must have their development files installed.

On Windows and Mac OS X, all the needed dependencies are provided directly with SFML, so you don't have to download/install anything. Compilation will work out of the box.

On Linux however, nothing is provided and SFML relies on your own installation of the libraries it depends on. Here is a list of what you need to install before compiling SFML:

The exact name of the packages depend on each distribution. And don't forget to install the development version of these packages.

Configuring your SFML build

This step consists of creating the projects/makefiles that will finally compile SFML. Basically it consists of choosing what to build, how to build it and where. Plus a few other options so that you can create the perfect build that suits your needs -- we'll see that in detail later.

The first thing to choose is where the projects/makefiles and object files (files resulting from the compilation process) will be created. You can generate them directly in the source tree (ie. the SFML root directory), but it will then be polluted with a lot of garbage: a complete hierarchy of build files, object files, etc. The cleanest solution is to generate them in a completely separate folder so that you can keep your SFML directory clean. Using separate folders will also make it easier to have multiple different builds (static, dynamic, debug, release, ...).

Now that you've chosen the build directory, there's one more thing to do before you can run CMake. When CMake configures your project, it tests the availability of the compiler (and checks its version as well). As a consequence, the compiler executable must be available when CMake is run. This is not a problem for Linux and Mac OS X users, since the compilers are installed in a standard path and are always globally available, but on Windows you may have to add the directory of your compiler in the PATH environment variable, so that CMake can find it automatically. This is especially important when you have several compilers installed, or multiple versions of the same compiler.

On Windows, if you want to use gcc (MinGW), you can temporarily add the MinGW\bin directory to the PATH and then run cmake from the command shell:

> set PATH=%PATH%;your_mingw_folder\bin
> cmake

With Visual C++, you can either run CMake from the "Visual Studio command prompt" available from the start menu, or call the vcvars32.bat file of your Visual Studio installation; it will setup the environment variables properly.

> your_visual_studio_folder\VC\bin\vcvars32.bat
> cmake

Now you are ready to run CMake. In fact there are three different ways to run it:

In this tutorial I will focus on cmake-gui, as this is most likely what beginners will use. I assume that people who use the command line can learn the syntax from the CMake manual. Except the screenshots and the "click there" stuff, all the explanations below still applies (options are the same).

Here is what cmake-gui looks like:

Screenshot of the cmake-gui tool

Here are the first steps to perform:

  1. Tell CMake where the source code of SFML is (this must be the root folder of the SFML hierarchy, where the first CMakeLists.txt file is).
  2. Choose where you want the projects/makefiles to be generated (if the directory doesn't exist, CMake will create it).
  3. Click the "Configure" button

If this is the first time that you run CMake in this directory (or if you cleared the cache), cmake-gui will ask you to choose the generator. In other words, this is where you select your compiler/IDE.

Screenshot of the generator selection dialog box

For example, to generate a Visual Studio 10 solution, you must choose "Visual Studio 10". To generate makefiles usable with Visual C++, select "NMake makefiles". To create makefiles usable with MinGW (gcc), select "MinGW makefiles". It is generally easier to generate makefiles rather than IDE projects: you can then compile with a single command, or even gather multiple compilations in a single script. Since you will only compile, not edit source files, IDE projects are generally useless.
Moreover, the installation process (described later in this document) may not work with the "Xcode" generator; therefore it is higthly recommended to use the "Makefile" generator on Mac OS X.

Always keep the "Use default native compilers" option, you don't need to care about the three others.

After selecting the generator, CMake will run a lot of tests to check various things of your compilation environment: compiler path, standard headers, SFML dependencies, etc. If everything is ok, it should finish with the "Configuring done" message. If something goes wrong, read the error(s) carefully. Maybe your compiler is not accessible (see above), or one external dependency is missing.

Screenshot of the cmake-gui window after configure

After configuring is done, a lot of options appear in the central part of the window. CMake has many options, but most of them have the right default value. Many of them are not even meant to be changed, they are just there to show you what CMake automatically found.
Here are the few relevant options that you may have to care about when configuring your SFML build:

Variable Meaning
CMAKE_BUILD_TYPE This option selects the build type. Relevant values are "Debug" and "Release" (there are other types such as "RelWithDebInfo" or "MinSizeRel", but they are not really configured in the SFML makefiles). Note that if you generate a workspace for an IDE that supports multiple configurations, such as Visual Studio, this option is ignored and you automatically get all the available build types in it.
CMAKE_INSTALL_PREFIX This is the install path. By default, it is defined to the most natural path according to the OS ("/usr/local" for Linux and Mac OS X, "C:\Program Files" for Windows, etc.). Installing files after compiling is not mandatory, you can use the binaries directly from where they are compiled, but it may be a better solution to install them properly so that you don't have all the garbage files produced by the compilation.
CMAKE_INSTALL_FRAMEWORK_PREFIX
(Mac OS X only)
This is the install path for frameworks. By default, it is defined to the root library, i.e. /Library/Frameworks folder. As stated for CMAKE_INSTALL_PREFIX it is not mandatory to install files after compiling, but it is cleaner to install them.
This path is used to install on your system sndfile.framework (a required dependency not provided by Apple) and SFML as frameworks if BUILD_FRAMEWORKS is selected.
BUILD_SHARED_LIBS This boolean option controls whether you build the dynamic (shared) libraries of SFML, or the static ones.
This option is not compatible with SFML_USE_STATIC_STD_LIBS, they are mutually exclusive.
SFML_BUILD_FRAMEWORKS
(Mac OS X only)
This boolean option controls whether you build SFML as framework bundles or as dylib binaries. Building frameworks requires BUILD_SHARED_LIBS to be selected.
It is recommended to use SFML as frameworks when releasing your applications to the public. However, SFML cannot be built in debug as frameworks; use instead dylibs.
SFML_BUILD_EXAMPLES This boolean option controls whether you build the SFML examples or not.
SFML_BUILD_DOC This boolean option controls whether you generate the SFML documentation or not. Note that the doxygen tool must be installed and accessible, otherwise enabling this option will produce an error.
On Mac OS X you can either install the classic-Unix doxygen binary into /usr/bin or any similar directory, or install Doxygen.app into any "Applications" folder, e.g. ~/Applications.
SFML_USE_STATIC_STD_LIBS
(Windows only)
This boolean option selects the version of the standard C/C++ library which is linked to SFML.
TRUE statically links the standard libraries, which means that SFML is self-contained and doesn't depend on the compiler's specific DLLs.
FALSE (the default) dynamically links the standard libraries, which means that SFML depends on the compiler's DLLs (msvcrxx.dll/msvcpxx.dll for Visual C++, libgcc_s_xxx-1.dll/libstdc++-6.dll for gcc). Be careful, this setting must match your own projects settings, otherwise you may experience crashes.
This option is not compatible with BUILD_SHARED_LIBS, they are mutually exclusive.
CMAKE_OSX_ARCHITECTURES
(Mac OS X only)
This setting specifies for which architectures SFML should be compiled. The recommended value is "i386;x86_64" to generate universal binaries for both 32 and 64 bits systems.
SFML_INSTALL_XCODE4_TEMPLATES
(Mac OS X only)
This boolean option controls whether cmake will install the Xcode 4 templates on your system or not. More information about these templates is given in the "Getting started" tutorial for Mac OS X.
SFML_INSTALL_PKGCONFIG_FILES
(Linux shared libraries only)
This boolean option controls whether cmake will install the pkg-config files on your system or not. pkg-config is a tool that provides a unified interface for querying installed libraries.

After everything is configured, click the "Configure" button once again: the options background should become white, and the "Generate" button should become available. Click it to finally create the chosen makefiles/projects.

Screenshot of the cmake-gui window after generate

CMake creates a cache for every project. Therefore, if you decide to come back later, you'll find your options back and you'll be able to change them, then reconfigure and generate the updated makefiles/projects.

C++11 and Mac OS X

If you want to use C++11 features in your application on Mac OS X, you have to use clang (Apple's official compiler) and libc++. Moreover, you also need to build SFML with these tools to workaround any incompatibility between standard libraries and compilers.

Here are the settings to use to build SFML with clang and libc++:

Screenshot of the compiler configuration on OS X

Building SFML

Let's start this new section with good news: you won't have to go through the configure step anymore, even if you update your working copy of SFML. CMake is smart, it adds a custom step to the generated makefiles/projects, that automatically regenerates the build files whenever something changes.

You're now ready to compile SFML. Of course, how to do it depends on what makefiles/projects you've generated. If you created a project/solution/workspace, open it with your IDE and compile like any other project. I won't show you the details here, there are too many different IDEs and I assume that you know yours enough to do this simple task.

If you generated a makefile, open a command shell and execute the make command corresponding to your environment. For example, run "nmake" if you generated a NMake (Visual C++) makefile, "mingw32-make" if you generated a MinGW (gcc) makefile, or simply "make" if you generated a Linux makefile.
Note: on Windows, the make program (nmake or mingw32-make) may not be accessible. If it's the case, don't forget to add it to your PATH environment variable; see the explanations at the beginning of the "Configuring your SFML build" section for more details.

By default, everything will be compiled (all the SFML libraries, as well as all the examples if you enabled the SFML_BUILD_EXAMPLES option). If you want to compile only a single SFML library or example, you can select a different target. You can also choose to clean or install the compiled files, with the corresponding targets.
Here are all the targets that are available, depending on the configure options that you chose:

Target Meaning
all This is the default target, it is used if no target is explicitly specified. It builds all the targets that produce a binary (sfml libraries and examples).
sfml‑system
sfml‑window
sfml‑network
sfml‑graphics
sfml‑audio
sfml‑main
Builds the corresponding SFML library. The "sfml-main" target is available only on Windows systems.
cocoa
ftp
opengl
pong
shader
sockets
sound
sound‑capture
voip
window
win32
X11
Builds the corresponding SFML example. These targets are available only if the SFML_BUILD_EXAMPLES option is enabled. Note that some of the targets are available only on a certain OS ("cocoa" is available on Mac OS X, "win32" on Windows, "X11" on Linux, etc.).
doc Generates the API documentation. This target is available only if the SFML_BUILD_DOC option is enabled.
clean Removes all the object files produced by a previous compilation. You generally don't need to invoke this target, except when you want to recompile SFML completely (some updates may mess up with object files already compiled, and cleaning everything is the only solution).
install Installs SFML to the path defined in the CMAKE_INSTALL_PREFIX and CMAKE_INSTALL_FRAMEWORK_PREFIX options. It copies the SFML libraries and headers, as well as examples and documentation if the SFML_BUILD_EXAMPLES and SFML_BUILD_DOC options are enabled. After installing, you get a clean distribution of SFML, just as if you had downloaded the SDK or installed it from the system repositories.

If you use an IDE, a target is simply a project. To build a target, select the corresponding project and compile it (even "clean" or "install" must be compiled to be executed -- don't be confused by the fact that no source code is actually compiled).
If you use a makefile, pass the name of the target to the make command to build this target. Examples: "nmake doc", "mingw32-make install", "make sfml-network".

Now you should have successfully compiled SFML. Congratulations!