A Brief Beginner’s Guide to CMake or How to quickly get up and running with CMake
C++ Python Shell CMake M4 Makefile C
Switch branches/tags
Nothing to show
Latest commit 4e338cf Feb 16, 2018
Permalink
Failed to load latest commit information.
lib add third-party library Feb 16, 2018
src Init Feb 16, 2018
test add third-party library Feb 16, 2018
.gitignore Init Feb 16, 2018
CMakeLists.txt add third-party library Feb 16, 2018
README.md Add IDE CLion support Feb 16, 2018

README.md

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:

cmake-tutorial/
├── CMakeLists.txt
├── README.md
├── lib
│   └── googletest
├── src
│   ├── main.cc
│   ├── math.cc
│   └── math.h
└── test
    └── math_test.cc

Directory structure:

  • lib : Directory for third party library.
  • src : Directory for source code.
  • test : Directory for test.

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

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 (kitware.com/cmake).

Compiling & Linking

We can build this project using the following command:

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

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

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

Using Makefile

We can automate the step to compile and link above using Makefile. First we need to write a Makefile with the following content:

math.o: src/math.cc src/math.h
    c++ -c src/math.cc -o math.o

cmake-tutorial: math.o
    c++ src/main.cc math.o -o cmake-tutorial

build: cmake-tutorial

Now we can run:

make build

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 build
make: Nothing to be done for `build'.

this is usefull 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
project(cmake-tutorial)

# Add definition for math library
add_library(math src/math.cc)

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

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

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/math.cc.o
[ 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/main.cc.o
[100%] Linking CXX executable cmake-tutorial
[100%] Built 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
add_subdirectory(lib/googletest)

# Test
add_executable(math_test test/math_test.cc)
target_link_libraries(math_test gtest)
target_link_libraries(math_test math)

Re-generate the build files using the following command:

cmake .

Build the unit test:

make math_test

Run the test:

% ./math_test 
[==========] Running 1 test from 1 test case.
[----------] Global test environment set-up.
[----------] 1 test from MathAddTest
[ RUN      ] MathAddTest.PositiveNum
[       OK ] MathAddTest.PositiveNum (0 ms)
[----------] 1 test from MathAddTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test case ran. (0 ms total)
[  PASSED  ] 1 test.

Done.

IDE Support

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

CLion