Blog Series Tags

CMake Include Directories

To do almost anything today with C++ requires the use of a number of different third party libraries. Some of these come in the form of header only libraries containing only include files (.h and .hpp). The references to these libraries are easy to resolve with CMake, let’s contrive an example.

Consider the following folder structure.

[CMakeHome] [CMakeHome]\src
Contains all the source code for the project

[CMakeHome]\headerlib\
Contains a small header only library with a number of different applications

[CMakeHome]\headerlib\math
Contains the math portion of the header only library.

Inside [CMakeHome]\headerlib\math we have the following code in max.hpp, a simple function to find the maximum value given two integers.

#ifndef INC_MAX_HPP
#define INC_MAX_HPP
int max(int a, int b) 
{ 
    if (a > b) 
        return a; 
    else 
        return b; 
}

Now in main.cpp in [CMakeHome]\src, we reference the function like so:

#include <iostream>
#include "math/max.hpp"
int main(int argc, char** argv) 
{
    int a = 5; int b = 10;
    int larger = max(a, b);
    std::cout << "Larger : " << larger << std::endl; 
}

This requires that the [CMakeHome]\headerlib\ folder be added to the include path during compilation. Here’s how we do it with CMake.

# The Minimum version of CMake this project requires
cmake_minimum_required(VERSION 2.8) 

# Project Name 
project (Main)

# Header only dependency
# We first find the directory 
find_path(headerlib_ROOT "") 
include_directories("${headerlib_ROOT}") 

# Sources 
file(GLOB Main_SOURCES *.cpp)

# Executable 
add_executable(main ${Main_SOURCES})

There’s just two extra lines of code (without the comments of course) in this CMake file in comparison to the last. find_path(headerlib_ROOT "") Requires CMake to try and find the path of headerlib (which it doesn’t) and store it in the variable headerlib_ROOT. The empty quotes could have contained a specific file that you want that directory to contain, but we can safely skip that bit for now. Since CMake doesn’t find the directory for headerlib_ROOT it prompts you for it adding a configuration item called headerlib_ROOT into it’s list of name value pairs.

Before you generate your makefiles or Visual Studio Projects you need to give it a path for the build to work correctly, because it’s that path that’s then used by the include_directories command. include_directories("${headerlib_ROOT}") The include_directories command adds the passed path into the include directories list of your preferred build tool.

The ${headerlib_ROOT} syntax is useful as it allows you to add further qualifiers at the end like for example: ${headerlib_ROOT}\math if we want to refer to the math directory directly. That’s it. You should now be able to generate your build files and build the code which will include the external library. You can use this method to get any header only library that CMake doesn’t have built in support to load.

This is a post in the CMake series.