Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

CMake Tutorial

This tutorial cover the following:

  1. Build the project using simple c++(1) and make(1).
  2. Build the project using cmake(1).
  3. Build the project using cmake(1) with third party library.

In this tutorial we will use the following project structure:

├── CMakeLists.txt
├── src
│   ├──
│   ├──
│   └── math.h
└── test

Directory structure:

  • src : Directory for source code.
  • test : Directory for test.

src/ is our main executable and src/math.{cc,h} is an internal library that used by src/

We will start from the basic on how to build the project using c++(1) only and a simple Makefile. Then we define the build in CMakeLists.txt and using cmake(1) to generate complex Makefile for us.

Install CMake

First of all, you need to install cmake.

On Ubuntu:

sudo apt-get install cmake

On macOS:

brew install cmake

Make sure the cmake is installed correctly:

% cmake --version
cmake version 3.10.2

CMake suite maintained and supported by Kitware (

Compiling & Linking

We can build this project using the following command:

c++ src/ src/ -o cmake-tutorial

Or we can do the compile and linking on the separate steps

c++ -c src/ -o math.o 
c++ src/ math.o -o cmake-tutorial

Using Makefile

We can automate the step to compile and link above using Makefile. First we need to create new Makefile in the root directory with the following content:

# Add definition to generate math.o object file
math.o: src/ src/math.h
    c++ -c src/ -o math.o

# Add definition to generate cmake-tutorial binary
cmake-tutorial: math.o
    c++ src/ math.o -o cmake-tutorial

Now we can run:

make cmake-tutorial

to build cmake-tutorial binary. If there are no changes in src/{main,math}.cc and src/math.h, the subsequent command will do nothing:

% make cmake-tutorial
make: Nothing to be done for `cmake-tutorial'.

this is useful when working on larger project, we only compile the object that changes.

Using CMake

Now we know how to perform compiling and linking using the C++ and make command. Now we can use cmake to do all of this for us.

Create new CMakeLists.txt with the following content:

cmake_minimum_required (VERSION 3.10)

# Define the project

# Add definition for math library
add_library(math src/

# Add definition for the cmake-tutorial binary
add_executable(cmake-tutorial src/
target_link_libraries(cmake-tutorial math)

We can generate the Makefile based on the definition above using the following command:

cmake .

Or create a build directory to store the generated files by CMake:

mkdir build
cd build/
cmake ..

Now we can run make cmake-tutorial to build the binary.

% make cmake-tutorial
Scanning dependencies of target math
[ 25%] Building CXX object CMakeFiles/math.dir/src/
[ 50%] Linking CXX static library libmath.a
[ 50%] Built target math
Scanning dependencies of target cmake-tutorial
[ 75%] Building CXX object CMakeFiles/cmake-tutorial.dir/src/
[100%] Linking CXX executable cmake-tutorial
[100%] Built target cmake-tutorial

Or we can use the CMake directly via:

cmake --build . --target cmake-tutorial

Using CMake with 3rd-party library

Suppose that we want to write a unit test for math::add(a, b). We will use a googletest library to create and run the unit test.

Add the following definition to CMakeLists.txt:

# Third-party library
    GIT_TAG "master"
# Prevent build on all targets build
set_target_properties(googletest PROPERTIES EXCLUDE_FROM_ALL TRUE)

# Define ${CMAKE_INSTALL_...} variables

# Specify where third-party libraries are located

# This is required for googletest
find_package(Threads REQUIRED)

# Test
add_executable(math_test test/
target_link_libraries(math_test math gtest Threads::Threads)
# Make sure third-party is built before executable
add_dependencies(math_test googletest)
set_target_properties(math_test PROPERTIES EXCLUDE_FROM_ALL TRUE)

Re-generate the build files using the following command:

cd build/
cmake ..

Build the unit test:

cmake --build . --target math_test

Run the test:

% ./math_test 
[==========] Running 6 tests from 3 test cases.
[----------] Global test environment set-up.
[----------] 2 tests from MathAddTest
[ RUN      ] MathAddTest.PositiveNum
[       OK ] MathAddTest.PositiveNum (0 ms)
[ RUN      ] MathAddTest.ZeroB
[       OK ] MathAddTest.ZeroB (0 ms)
[----------] 2 tests from MathAddTest (0 ms total)

[----------] 2 tests from MathSubTest
[ RUN      ] MathSubTest.PositiveNum
[       OK ] MathSubTest.PositiveNum (0 ms)
[ RUN      ] MathSubTest.ZeroB
[       OK ] MathSubTest.ZeroB (0 ms)
[----------] 2 tests from MathSubTest (0 ms total)

[----------] 2 tests from MathMulTest
[ RUN      ] MathMulTest.PositiveNum
[       OK ] MathMulTest.PositiveNum (0 ms)
[ RUN      ] MathMulTest.ZeroB
[       OK ] MathMulTest.ZeroB (0 ms)
[----------] 2 tests from MathMulTest (0 ms total)

[----------] Global test environment tear-down
[==========] 6 tests from 3 test cases ran. (0 ms total)
[  PASSED  ] 6 tests.


IDE Support

If you are using CLion, the google test will automatically detected.


Visual studio also support cmake


A Brief Beginner’s Guide to CMake or How to quickly get up and running with CMake







No releases published


No packages published