An introduction to CMake

09 Apr 2020

"CMake is a cross-platform free and open-source software tool for managing the build process of software using a compiler-independent method." - Wikipedia

What does it mean? Why do you need a tool like CMake?

Let us assume that you have a C++ project and you want to distribute your software in different operating systems like Windows, Linux and MacOS. In order to do that, you need to compile your project natively in all the three platforms. Now to accomplish that consider the main compilers and project files available for these platforms.

The popular compiler in Linux/MacOS is GCC and in Windows, it would be Microsoft Visual Studio compiler. If your project is huge, then it would make sense to use a project/make file to efficiently compile your project. A suitable choice in Linux/MacOS will be using a MakeFile and in Windows, one would need Visual Studio solution file. Now to maintain the codebase in multiple platforms, we need to maintain these MakeFile/project files separately and this would be a tedious task and would be prone to lot of errors.

Here comes the advantage of using a tool like CMake. CMake can generate the MakeFile/project files in different platforms from a single input configuration file. And the developer has to maintain only one project/configuration file across multiple platforms. CMake also helps the developer to keep the build folder outside its source directory and thus helps to maintain the source code folder clean without any build generated artifacts. Now let us see how we can create a simple project using CMake.

The input configuration file for CMake is named as CMakeLists.txt. Lets take an example. Assume that the following is folder structure for our code base.

|______src --> main.cpp

Here src is the folder containing our source folder and build directory is the folder where we generate the project file. Now lets define the contents of the CMakeLists.txt files. A typical CMakeLists.txt file would contain the following structure,

cmake_minimum_required( VERSION 3.0 )
project( sample_project )
add_executable( ${PROJECT_NAME} src/main.cpp )

cmake_minimum_required( VERSION 3.0 ) specifies the minimum version of CMake required for the project.
project( sample_project ) specifies the name of the project
add_executable( ${PROJECT_NAME} src/main.cpp ) specifies the target to be created and the list of source files. Here ${PROJECT_NAME} is a special variable in the CMake framework which would give the project name we mentioned in the previous line. CMake contains several special variables which are helpful when writing complex CMake projects.

Now to run this we will go to the folder where we wish to generate the build files and final executable. Here in this case, we will be using the build folder to generate the build files. Run the following command from the build folder,

cmake -G "Visual Studio 16 2019" ../

This command will generate the build files in the current folder from where it is run. The -G option specifies the project file to be generated and ../ specifies the relative location of the CMakeLists.txt file from the build folder. cmake --help will give the list of supported generators.

Once the build files are generated, the code can be compiled by running,

cmake build

This will generate the executable file after successfull compilation.

CMake can be downloaded from the Kitware website.