How to Properly Add Include Directories With Cmake

How to properly add include directories with CMake

Two things must be done.

First add the directory to be included:

target_include_directories(test PRIVATE ${YOUR_DIRECTORY})

In case you are stuck with a very old CMake version (2.8.10 or older) without support for target_include_directories, you can also use the legacy include_directories instead:

include_directories(${YOUR_DIRECTORY})

Then you also must add the header files to the list of your source files for the current target, for instance:

set(SOURCES file.cpp file2.cpp ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_executable(test ${SOURCES})

This way, the header files will appear as dependencies in the Makefile, and also for example in the generated Visual Studio project, if you generate one.

How to use those header files for several targets:

set(HEADER_FILES ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)

add_library(mylib libsrc.cpp ${HEADER_FILES})
target_include_directories(mylib PRIVATE ${YOUR_DIRECTORY})
add_executable(myexec execfile.cpp ${HEADER_FILES})
target_include_directories(myexec PRIVATE ${YOUR_DIRECTORY})

How can i include header files from a directory into cmake

You need to tell CMake to add includes/to your program's include path. Usually this is done with either include_directories or target_include_directories

add_executable (HelloWorld ${source_files})

# Assuming this is meant to be a public directory
target_include_directories(HelloWorld PUBLIC "includes/")

cmake find all directories by name on the include path and add them to the include path

CMake doesn't provide a way for a custom iteration over include directories.
Instead, you could reformulate your intentions into the form "find a directory with the given header".

That form is expressed with command find_path, which is a natural way in CMake for search include directories.

E.g. that call:

# Task for CMake: Find a directory with "begin_code.h" header in it.
# Possibly, this is subdirectory 'SDL2' of a "normal" include directory.
find_path(SDL2_INCLUDE_DIR_1 "begin_code.h" PATH_SUFFIXES "SDL2")

will fill the variable SDL2_INCLUDE_DIR_1 with the directory containing the header begin_code.h.

This way works perfectly in case of local installation of SDL2, if that installation is hinted for CMake with CMAKE_PREFIX_PATH variable. For support other hints, e.g. SDL2DIR environment variable, you need to add appropriate PATHS options to your call:

find_path(SDL2_INCLUDE_DIR_1 "begin_code.h" PATH_SUFFIXES "SDL2" PATHS ENV SDL2DIR)

If you feel that SDL2 developers could rename the problematic file, but expect that file to be near the SDL2.h, then you could change the above command to search SDL2.h instead of begin_code.h:

find_path(SDL2_INCLUDE_DIR_1 "SDL2.h" PATH_SUFFIXES "SDL2" PATHS ENV SDL2DIR)

Cmake include_directories()

Quoting the documentation for include_directories:

The include directories are added to the directory property
INCLUDE_DIRECTORIES for the current CMakeLists file. They are also
added to the target property INCLUDE_DIRECTORIES for each target in
the current CMakeLists file. The target property values are the ones
used by the generators.

The INCLUDE_DIRECTORIES directory property is inherited to all subdirectories and all targets in the directory.

  • Specifying ${CMAKE_CURRENT_SOURCE_DIR} for include_directories is redundant as relative paths are interpreted as relative to this directory by default. You should throw it out to increase readability.
  • Specifying an include directory in both a subdirectory and its parent is redundant. You should avoid this and settle on one location.
  • Use get_property and message to double-check that all directories and targets end up with the correct entries in their INCLUDE_DIRECTORIES property.
  • If you are free to require CMake 2.8.11 as a minimum requirement, consider abandoning include_directories completely and use target_include_directories instead. This has the advantage that include dependencies get resolved on a per-target basis exclusively which is usually the more desirable behavior.

CMake isn't able to include header file into my source file

It's ${CMAKE_CURRENT_SOURCE_DIR}, not ${CMAKE_CURRENT_SRC_DIR}.

If you fix this then the compiler should see the correct include directory.

At the moment because the variable doesn't exist, the only directory it sees is /include which is not what you want.



Related Topics



Leave a reply



Submit