Your start with CMake: As simple as it can get

January 31, 2023

When I recently started to work with CMake for a C++ project, I did find it challenging to get started with. The documentation is comprehensive but can be overwhelming. There are of course multiple helpful articles and tutorials around, but I was already struggling with the simplest commands.

This article is mainly for the people, who use CMake for the first time. I will try to use as less words and to be as clear as possible. Surely it will not be complete and I can not guarantee full correctness. Comments and corrections are welcome!

Find the whole source code at Github: https://github.com/digitsensitive/cmake-starter

What is CMake?

CMake is an extensible, open-source system that manages the build process in an operating system and in a compiler-independent manner (taken from the official website). There are alternative tools.

This all sounds good. But seriously, what is CMake exactly and why should I use it?

You should use it, because with one configuration file (CMakeLists.txt) you can generate standard build files to be used by a native build environment (f.e. Make, Apple’s Xcode, Qt Creator, Ninja, Microsoft Visual Studio) to create the actual building (= your application). You can get full flexibility and make your project more future-proof.

CMake has minimal dependencies, requiring only a C++ compiler on its own build system.

Let’s dive in

Enough general talk: Let’s create our first (very complicated!) C++ project:

int main() {
  return 0;
}

This is our main.cpp file and I have placed it into a folder called src. Additionally we need a folder named build in the root.

We place our CMake configuration file (CMakeLists.txt) in the root. This is our final folder tree structure:

.
├── CMakeLists.txt
├── build
└── src
    └── main.cpp

At this point make sure you have CMake installed on your computer!

CMakeLists.txt

For the rest of this article, we will focus on creating our first simple configuration file. You can find the whole configuration file in the source code repository linked in the article.

cmake_minimum_required(VERSION 3.18.1)

At first you should set the minimum required CMake version. If your local version of CMake is lower than the minimum, it will stop processing the project and report an error. You might want to set three variables VERSION_MAJOR, VERSION_MINOR and VERSION_REVISION and use them (as it is in the github repository).

set(CMAKE_CXX_STANDARD 11)

Next we set the variable CMAKE_CXX_STANDARD to define the C++ standard whose features we request to build the project. Supported values are 98, 11, 14, 17, and 20.

set(CMAKE_CXX_STANDARD_REQUIRED ON)

Now we want to set the C++ standard to be required. For this we set the variable CMAKE_CXX_STANDARD_REQUIRED to ON.

project(myProject VERSION 0.1.0)

We can now set our project name and the version (optional). More optional variables are DESCRIPTION, HOMEPAGE_URL and LANGUAGES. From now on you can refer to your project name with the variable PROJECT_NAME, which is recommended to minimize typing errors.

add_executable(${PROJECT_NAME} src/main.cpp)

Finally we add an executable to our project, for which we use our predefined variable PROJECT_NAME. We also add a list of our source files.

At this point we are done with our basic CMakeLists.txt file.

cmake_minimum_required(VERSION 3.18.1)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
project(myProject VERSION 0.1.0)
add_executable(${PROJECT_NAME} main.cpp)

Generate!

With our CMakeLists.txt file we finished our project. We can now generate the standard build files (= a project build system). Open your terminal and navigate to the empty build folder.

cmake ..

With cmake you access the command-line interface of the buildsystem generator CMake. With the .. you hand over the path to the source. This path must contain a CMakeLists.txt file. Now you should have your build files!

Finally we want to build the executable file. I use make, so I simply have to run the following command in the build folder:

make

If you like you can replace this line and use this instead:

cmake --build

This will call make or whatever build tool you are using.

This is it. There would be much more to write. But I guess that is enough for a start. Comments or corrections are always welcome!

Modern CMake

After publishing this story I received important and helpful advises. I want to sum it up here:

I just began to read about Modern CMake and can recommend the following ressources:

References

Build system C C++ Cplusplus CMake CMakeLists.txt Cross-platform Dependencies Generators Libraries Object-Oriented Programming