A brief overview of how CMake works. More...
A brief overview of how CMake works.
Table of contents:
CMake is a tool designed to help developers get rid of the challenges associated with writing Makefiles in projects. CMake is designed to be portable across many types of systems, and can generate native build scripts for many different compilers on several different operating systems. We will be giving a cursory overview of the CMake and explain how you can use it with your own client applications.
Directory structure
A project directory typically contains the following subdirectories:
- src : Contains the source code that gets compiled. Often times, the
srcfolder contains information for only one executable or libarary, but it is possible to have multiple executables per directory. - doc : Contains the project documentation. If you use doxygen or any other program for autogenerating your documentation, it is a good idea to build a
Makefileso you can runmakedocto automatically generate the documentation.
Player has a slightly different (and larger directory structure), which works with generally the same principles.
Configuration files
CMake uses various CMakeLists.txt files, usually one in each directory of the project. These files contain logic to set build options, resolve external project dependencies, and add executable and library targets. Custom targets and macros can also be defined and included into the CMake files.
A brief example
Sometimes the best way to explain a topic is by showing an example. Here, we will be building a project that uses CMake to build a c++ client application. All of the code for this example is include in examples/tutorials/cmake
Base directory
CMake requires at least one CMakeLists.txt file for project configuration. Generally, projects distribute the configuration, and place a CMakeLists.txt in each subdirectory of the source tree as well. This allows you to keep things modular: the base directory CMakeLists.txt can handle setting global configuration (project name, version, project dependency discovery), and the subdirectory files can handle.
The command CMAKE_MINIMUM_VERSION defines the minimum version of CMake that is required to process the CMakeLists.txt file. This is to handle CMake API compatibility; as new functions are added, older versions of CMake won't be able process newer files. In general, we recommend version 2.6 and above.
The PROJECT macro sets your project's name. This can be useful in setting project install directories, but is not required. The PROJECT_VERSION variable is similar; if you're not creating a large project you probably don't need to worry about these variables.
The CMAKE_C_FLAGS and CMAKE_CXX_FLAGS are the build flags that will be applied to all C and C++ files in the project. You can set the CMake variable CMAKE_BUILD_TYPE to "DEBUG" or "RELEASE" to switch between the two types of build flags. This can be accomplished in the ccmake curses-based UI, or by using the -D option on the CMake command line. For example:
$ cmake -D CMAKE_BUILD_TYPE=RELEASE
CMake does not generate a "make uninstall" target by default. ADD_CUSTOM_TARGET allows you to add uninstall target. This particular method was borrowed from the CMake FAQ.
Finally, the ADD_SUBDIRECTORY commands tell CMake to traverse to the "doc" and "src" subdirectories and process the CMakeLists.txt files in those directories.
- Note
- If you are installing Player on a machine, you need to make sure that the PKG_CONFIG_PATH that the code installed to is included in your search path. If you are using a bash shell, you can enter the following (or something similar) in your ~/.bashrc.
# for .pc in /usr/local export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig/
Source directory
A CMakeLists.txt contains directives on how to build, link, and install libraries and executables. We will discuss some of the macros that Player includes for building plugin drivers and client programs, but the rest are beyond the scope of the document. The following CMakeLists.txt file builds a Player C++ client program and a Player example driver library.
Setting the CMAKE_MODULE_PATH tells CMake where it can search for additional modules when the INCLUDE command is used. If Player isn't installed to /usr, the path where Player is installed needs to be added so CMake will be able to find Player's CMake modules.
The INCLUDE command will load a CMake module for use in your CMakeLists.txt. The UsePlayerC++ and UsePlayerPlugin CMake modules provide useful macros for building and linking C++ clients and plugin drivers, respectively.
PLAYER_ADD_PLAYERCPP_CLIENT is one of the macros in UsePlayerC++. It uses the ADD_EXECUTABLE command from CMake to create an executable client program, and handles adding all of the include directories and link libraries needed to compile against Player. More details about the macros Player provides can be found on the Player wiki.
Generating documentation
To demonstrate another aspect of the CMakeLists.txt files we will setup code to allow you to run the command make doc and build doxygen comments. To use Doxygen to automatically generate documentation you typically type the command:
$ doxygen example.dox
where example.dox is a doxygen configuration file typically generated by a tool such as doxywizard. To accomplish the same thing with your Makefile, you can utilize the fact that you can create custom build targets with any arbitrary commands using @ CMake. The following creates a rudimentary build target to build documentation using Doxygen:
Generating the build scripts
You need to run the CMake program in order to generate project @ Makefiles from the @ CMakeLists.txt files. Generally, it is encourged to do an "out of tree build." This constitutes creating a separate folder in the base directory of your project, usually called build. From this build folder, you can invoke CMake and generate the build scripts. The out-of-tree build has the advantage of keeping all of the generated build scripts away from the source files, so they can be easily removed or ignored using a .gitignore or .svnignore. You can do an out-of-tree build like this:
$ mkdir build $ cd build $ cmake ..
After generating the scripts, you can run the typical make command as usual to build the project.
Build options
After successfully running the CMake program the following options are avaliable for make
make: Builds the project and creates the executables and libraries.makeclean: Cleans the project i.e removes all the executables.makeinstall: Builds and installs the project i.e the executable is copied in the /prefix/bin,headers in /prefix/include and libraries in /prefix/lib where prefix is usually /usr/local.makeuninstall: Uninstalls the project i.e removes the files added to /prefix/bin, /prefix/include and /prefix/lib directories.makedoc: Creates project documentation

