Manoj Rao bio photo

Manoj Rao

Your Average Common Man

Email Twitter Github

In this post, we will walk through a dummy cmake setup for a C++ application. For the experienced folks this is not going to be very informative, however, can serve as a reference to start building complex projects with.

A Simple Application

I want to create a project called my_app with the following directory structure.

├── CMakeLists.txt
├── src
│   └── main.cc
├── test
│   ├── CMakeLists.txt
│   └── my_app_test.cc
└── third-party
    └── googletest -> /home/manoj/software/googletest

CMakeLists.txt

cmake is not really a replacement for make instead it is a generator of Makefile or other alternatives such as Ninja files.

Basic Config

cmake makes frequent releases, so this will require you to set a minimum required version.

cmake_minimum_required(VERSION 3.16)

Set the compiler version and the language standard version.

# Compiler and Standard
set(CMAKE_C_STANDARD 99)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_COMPILER clang-8)
set(CMAKE_CXX_COMPILER clang++-8)

I prefer to set the global project name in a variable and use that all over the rest of the file so that file is readable.

# set the project name
set(this_project my_app)

It’s nice to use variables for other project directories too.

# third party software
set(thirdparty third-party)

Here you are telling which languages are used in the project.

# RUST, Erlang, what else
project(${this_project} C CXX)

Here you are telling that you want to enable testing for this dir and it’s subdirs

enable_testing()

This is used to add googletest as your testing software.

# add google test
add_subdirectory(${thirdparty}/googletest)

Specify the source files and headers

# header files
set(headers
  include/my_app.h
  )

# src files
set(sources
  src/main.cc
  )

Finally, build the executable for this project

# add the executable
add_executable(${this_project} ${sources} ${headers})

I have not tested these, but they are useful if you are building library

target_include_directories(${this_project} PUBLIC include)
target_include_directories(${this_project} PRIVATE src)

The directory consisting tests and it’s own CMakeLists.txt

add_subdirectory(test)

Nice options, especially useful if you are using them with Emacs rtags

set(CMAKE_ENABLE_EXPORTS ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

My Podcast!

If you like topics such as this then please consider subscribing to my podcast. I talk to some of the stalwarts in tech and ask them what their favorite productivity hacks are:

Available on iTunes Podcast

Visit Void Star Podcast’s page on iTunes Podcast Portal. Please Click ‘Subscribe’, leave a comment.

Get it iTunes

Available on Google Play Music

Visit Void Star Podcast’s page on Google Play Music. Please Click ‘Subscribe’ and leave a comment.

Listen on Google Play Music
Available on Stitcher

Visit Void Star Podcast’s page on Sticher. Please Click ‘Subscribe’ and leave a comment.

Listen to Stitcher

Your app not listed here? Not an issue..

You should be able to search for ‘VoidStar Podcast’ on your favorite app. Most apps use one of the above sources for listing podcasts. This was tested on Podcast Addict (where you can also specify the search engine) and RatPoison on Android.