pages tagged SFML
Beuc's Blog
https://blog.beuc.net/tags/SFML/
Beuc's Blog
ikiwiki
2020-01-04T23:50:31Z
Build a SFML project with CMake
https://blog.beuc.net/posts/Build_a_SFML_project_with_CMake/
2020-01-04T23:50:31Z
2011-11-01T20:13:45Z
<p>[Latest version of these instructions can be found at the <a href="https://github.com/LaurentGomila/SFML/wiki/TutorialCMake">SFML Wiki</a>]</p>
<p>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.</p>
<p>In this tutorial we'll write a simple CMake configuration file with centralized version numbering, and see how to integrate SFML in it.</p>
<h1>The source files</h1>
<p>First, create a <code>cmake_modules</code> directory and copy <a href="https://github.com/LaurentGomila/SFML/blob/master/cmake/Modules/FindSFML.cmake">FindSFML.cmake</a> in it. FindXXXX is automatically searched by CMake's <code>find_package</code> command.</p>
<p>Then create a main.cpp, for instance:</p>
<div class="highlight-c++"><pre class="hl"><span class="hl ppc">#include</span> <span class="hl pps">"config.h"</span><span class="hl ppc"></span>
<span class="hl ppc">#include <iostream></span>
<span class="hl ppc">#include <SFML/Window.hpp></span>
<span class="hl kwa">using namespace</span> std<span class="hl opt">;</span>
<span class="hl kwb">int</span> <span class="hl kwd">main</span><span class="hl opt">(</span><span class="hl kwb">int</span> argc<span class="hl opt">,</span> <span class="hl kwb">char</span><span class="hl opt">*</span> argv<span class="hl opt">[]) {</span>
cout <span class="hl opt"><<</span> <span class="hl str">"Version "</span> <span class="hl opt"><<</span> myproject_VERSION_MAJOR <span class="hl opt"><<</span> <span class="hl str">"."</span> <span class="hl opt"><<</span> myproject_VERSION_MINOR <span class="hl opt"><<</span> endl<span class="hl opt">;</span>
<span class="hl kwc">sf</span><span class="hl opt">::</span>Window <span class="hl kwd">screen</span><span class="hl opt">(</span><span class="hl kwc">sf</span><span class="hl opt">::</span><span class="hl kwd">VideoMode</span><span class="hl opt">(</span><span class="hl num">800</span><span class="hl opt">,</span> <span class="hl num">600</span><span class="hl opt">),</span> <span class="hl str">"myproject"</span><span class="hl opt">);</span>
<span class="hl kwb">bool</span> running <span class="hl opt">=</span> <span class="hl kwa">true</span><span class="hl opt">;</span>
<span class="hl kwa">while</span> <span class="hl opt">(</span>running<span class="hl opt">) {</span>
screen<span class="hl opt">.</span><span class="hl kwd">Display</span><span class="hl opt">();</span>
<span class="hl opt">}</span>
<span class="hl opt">}</span>
</pre></div>
<p>We use a <code>config.h</code> file that is built by CMake, let's also create a <code>config.h.in</code> file:</p>
<div class="highlight-c++"><pre class="hl"><span class="hl ppc">#define myproject_VERSION_MAJOR @myproject_VERSION_MAJOR@</span>
<span class="hl ppc">#define myproject_VERSION_MINOR @myproject_VERSION_MINOR@</span>
</pre></div>
<p>And place your project license (such as the <a href="http://www.gnu.org/copyleft/gpl.html">GNU GPL</a>) in a file named <code>COPYING</code>.</p>
<h1>CMake configuration</h1>
<p>Let's describe our project configuration in the <code>CMakeLists.txt</code> file:</p>
<div class="highlight-make"><pre class="hl">cmake_minimum_required<span class="hl opt">(</span>VERSION <span class="hl num">2.6</span><span class="hl opt">)</span>
project<span class="hl opt">(</span>myproject<span class="hl opt">)</span>
<span class="hl slc"># Set version information in a config.h file</span>
set<span class="hl opt">(</span>myproject_VERSION_MAJOR <span class="hl num">1</span><span class="hl opt">)</span>
set<span class="hl opt">(</span>myproject_VERSION_MINOR <span class="hl num">0</span><span class="hl opt">)</span>
configure_file<span class="hl opt">(</span>
<span class="hl str">"${PROJECT_SOURCE_DIR}/config.h.in"</span>
<span class="hl str">"${PROJECT_BINARY_DIR}/config.h"</span>
<span class="hl opt">)</span>
include_directories<span class="hl opt">(</span><span class="hl str">"${PROJECT_BINARY_DIR}"</span><span class="hl opt">)</span>
<span class="hl slc"># Define sources and executable</span>
set<span class="hl opt">(</span>EXECUTABLE_NAME <span class="hl str">"myproject"</span><span class="hl opt">)</span>
add_executable<span class="hl opt">(${</span><span class="hl kwc">EXECUTABLE_NAME</span><span class="hl opt">}</span> main.<span class="hl kwa">cpp</span><span class="hl opt">)</span>
<span class="hl slc"># Detect and add SFML</span>
set<span class="hl opt">(</span>CMAKE_MODULE_PATH <span class="hl str">"${CMAKE_SOURCE_DIR}/cmake_modules"</span> <span class="hl opt">${</span><span class="hl kwc">CMAKE_MODULE_PATH</span><span class="hl opt">})</span>
find_package<span class="hl opt">(</span>SFML <span class="hl num">1.6</span> REQUIRED system window graphics network audio<span class="hl opt">)</span>
target_link_libraries<span class="hl opt">(${</span><span class="hl kwc">EXECUTABLE_NAME</span><span class="hl opt">} ${</span><span class="hl kwc">SFML_LIBRARIES</span><span class="hl opt">})</span>
<span class="hl slc"># Install target</span>
<span class="hl kwa">install</span><span class="hl opt">(</span>TARGETS <span class="hl opt">${</span><span class="hl kwc">EXECUTABLE_NAME</span><span class="hl opt">}</span> DESTINATION bin<span class="hl opt">)</span>
<span class="hl slc"># CPack packaging</span>
<span class="hl kwb">include</span><span class="hl opt">(</span>InstallRequiredSystemLibraries<span class="hl opt">)</span>
set<span class="hl opt">(</span>CPACK_RESOURCE_FILE_LICENSE <span class="hl str">"${CMAKE_SOURCE_DIR}/COPYING"</span><span class="hl opt">)</span>
set<span class="hl opt">(</span>CPACK_PACKAGE_VERSION_MAJOR <span class="hl str">"${myproject_VERSION_MAJOR}"</span><span class="hl opt">)</span>
set<span class="hl opt">(</span>CPACK_PACKAGE_VERSION_MINOR <span class="hl str">"${myproject_VERSION_MINOR}"</span><span class="hl opt">)</span>
<span class="hl kwb">include</span><span class="hl opt">(</span>CPack<span class="hl opt">)</span>
</pre></div>
<p>The interesting part is:</p>
<div class="highlight-make"><pre class="hl"><span class="hl slc"># Detect and add SFML</span>
set<span class="hl opt">(</span>CMAKE_MODULE_PATH <span class="hl str">"${CMAKE_SOURCE_DIR}/cmake_modules"</span> <span class="hl opt">${</span><span class="hl kwc">CMAKE_MODULE_PATH</span><span class="hl opt">})</span>
find_package<span class="hl opt">(</span>SFML <span class="hl num">1.6</span> REQUIRED system window graphics network audio<span class="hl opt">)</span>
target_link_libraries<span class="hl opt">(${</span><span class="hl kwc">EXECUTABLE_NAME</span><span class="hl opt">} ${</span><span class="hl kwc">SFML_LIBRARIES</span><span class="hl opt">})</span>
</pre></div>
<ul>
<li>First we specify where we stored the FindSFML.cmake module.</li>
<li>Then we request CMake to look for it in the system, and search for the specified modules (here I specified them all).</li>
<li>Last, we tell CMake to link our executable with the SFML libraries that it just found.</li>
</ul>
<h1>Compilation</h1>
<p>To build with Make and the GCC compiler on the command-line:</p>
<div class="highlight-bash"><pre class="hl"><span class="hl kwb">cd</span> build<span class="hl opt">/</span> <span class="hl slc"># a separate directory so we can easily remove all the CMake work files</span>
cmake .. <span class="hl slc"># generate Makefile's</span>
<span class="hl kwc">make</span>
</pre></div>
<p>To create Code::Blocks project files:</p>
<div class="highlight-bash"><pre class="hl">cmake .. <span class="hl kwb">-G</span> <span class="hl str">"CodeBlocks - Unix Makefiles"</span>
</pre></div>
<p>and open <code>project.cbp</code> with Code::Blocks.</p>
<h1>Installation</h1>
<p>CMake supports the classic:</p>
<div class="highlight-bash"><pre class="hl"><span class="hl kwc">make install</span>
</pre></div>
<p>It also supports DESTDIR, useful in packaging:</p>
<div class="highlight-bash"><pre class="hl"><span class="hl kwc">make install</span> DESTDIR<span class="hl opt">=</span><span class="hl str">`pwd`</span><span class="hl opt">/</span>myworkdir
</pre></div>
<p>You can also define <code>CMAKE_INSTALL_PREFIX</code> when invoking <code>cmake</code> to change the default install path (<code>/usr/local</code> under Unix). DESTDIR would still override this setting.</p>
<h1>Packaging</h1>
<p>You then can use <code>cpack</code> to make a project release:</p>
<div class="highlight-bash"><pre class="hl"><span class="hl slc"># Binary package:</span>
cpack <span class="hl kwb">-C</span> CPackConfig.cmake
<span class="hl slc"># Source package:</span>
cpack <span class="hl kwb">-C</span> CPackSourceConfig.cmake
</pre></div>
<p>You will get a nice <code>myproject-1.0.tar.gz</code>, among others.</p>
<h1>Further information</h1>
<ul>
<li>CMake has built-in help, for instance:</li>
</ul>
<div class="highlight-bash"><pre class="hl">$ cmake <span class="hl kwb">--help-variable</span> CMAKE_SOURCE_DIR
cmake version <span class="hl num">2.8.5</span>
CMAKE_SOURCE_DIR
The path to the top level of the <span class="hl kwb">source</span> tree.
This is the full path to the top level of the current CMake <span class="hl kwb">source</span>
tree. For an in-source build<span class="hl opt">,</span> this would be the same as
CMAKE_BINARY_DIR.
</pre></div>
<ul>
<li><a href="http://www.cmake.org/cmake/help/cmake-2-8-docs.html#command:target_link_libraries2-8-docs.html">Reference for v2.8</a></li>
<li><a href="http://www.cmake.org/cmake/help/cmake_tutorial.html">CMake Tutorial</a></li>
</ul>