Coding Literature A Blog about C++ and everything.

CMake

CMake is an open source cross platform tool to build software projects. CMake generates build pipeline for the platform, which is then used to build the project. In simpler language, CMake generates files required to build the project. For a C++ project, the output of CMake is a build pipeline which can be anything from a Visual Studio Project to Linux Makefiles, based on the selected generator.

CMake introduces a lot of complexity into the build system but fear not as this complexity is abstracted from the user. A user is never expected to modify the generated build pipeline.

To use CMake, a CMakeLists.txt file is required in the source directory of the project. This file contains all the build instructions. A recommended way to build a project is to create a new directory named build, which is different from the source directory. From the build directory, execute cmake <Source Directory>

This will generate a build pipeline. For the sake of simplicity, let’s assume we are on a linux machine, and the build pipeline generated is a Makefile. Generating build pipeline in a seperate build directory have the advantage of seperating the build files from project source files. All the build artifacts are in this directory, and can be deleted for cleanup.

The most basic CMake for a project is:

cmake_minimum_required(VERSION 2.9)
project(BasicProject)
add_executable(BasicProject, main.cpp)

Some Interesting Cmake Command Arguments

  • cmake <source directory> -p runs the script but don’t generate a pipeline.
  • cmake <source directory> -j n, runs the build process on n threads in parallel, if possible.

CMake is more like a scripting language and is very flexible. Let’s go over the basic building blocks of CMake Scripting.

message

message("Building Core library.") message prints the message. Very useful for printing status messages.

Variables

Every varible in CMake is a string. A variable is reference by specifying the name of variable in ${}. This is also known as variable reference. Variables can be set by:

  • Set command set (Number, 42) This sets the variable Number to 42. The statement message("The Ultimate Answer is ${Number}") prints The Ultimate Answer is 42.
  • Varibles can be defined on command line $ cmake -DNumber 42 Quotes around arguments are optional as long as there are no spaces or reference variable.

Flow Control

Cmake supports if statement and while loop.

    if(Linux)
      message("Building on Linux")
    endif()
    while(num LESS 42)
      message("Number is still less than 42.")
   endwhile()

Including Scripts

include ( <FileName.cmake> ) command is used to load and execute CMake from other the file provided. This is generally used to find third party packages. For example, a project using Boost, may have include (Boost.cmake) which can be used to find boost installation before building.

add_subdirectory ( <source subdirectory> ) creates a new scope and executes the CMakeLists.txt from the subdirectory.

Include Directories

To set up the include directories include_directories ( <directoryName> ) is used.

Libraries

To set up the link library directories (just like LD_LIBRARY_PATH) link_directories ( <directoryName> ) is used.
And to link libraries, target_link_libraries( <target> PRIVATE "lib1.a lib2.a")

Targets

add_executable, add_library, add_custom_target commands defines targets. For example,

  add_executable (MyBinary, MyBinary.cpp)         \\Creates binary named MyBinary
  add_executable (CoolStuffBinary, CoolStuff.cpp) \\Creates binary named MyBinary
  add_library (MySharedLib, SHARED, SharedLibCode.cpp)  \\Creates Shared library named MySharedLib.so
  add_library (MyStaticLib, STATIC, SharedLibCode.cpp)  \\Creates Shared library named MyStaticLib.a

Here CMake creates build targets for each executable. By default an all target is also created is executed if no specific target is specified.

pending stuff about custom_target

Custom Commands

pending explanation

A self-explanatory CMakeLists.txt Example


Scratching the Surface

There is so much more in CMake, that this post can barely scratch the surface. Some other interesting features in cmake include generators, regular expressions etc.