Cmake include_directories()
Asked Answered
S

2

17

This is my project tree:

project
| + src
| + external
| | + foo
| | | + include
| | | | - foo.hpp
| | | + src
| | | | - foo.cpp
| | | | - CMakeLists.txt
| | | - CMakeLists.txt 
| | + CMakeLists.txt 
| + src
| | - main.cpp
| - CMakeLists.txt

foo.cpp includes foo.hpp:

// foo.cpp
#include "foo.hpp"

Now the problem is that including the directory in the top CMake successfully find foo.hpp, but if I include in the subproject it doesn't. Any reason for it? (directories are included before the executable is compiled).

// project/CMakeLists.txt
include_directories(external/foo/include) //OK
add_subdirectory(external)

add_executable(main main.cpp)
target_link_libraries(main foo)

// project/external/CMakeLists.txt
add_subdirectory(foo)

// project/external/foo/CMakeLists.txt 
include_directories(include) // NOT WORKING
add_subdirectory(src)

// project/external/foo/src/CMakeLists.txt 
add_library(foo foo.cpp)
Sweitzer answered 14/11, 2013 at 15:23 Comment(4)
There seems to be a mismatch between external/include in the top-level CMakeList and external/foo/include in the CMakeList inside foo - perhaps that's the issue?Peplum
I made some edits, there might have been some errors before, but it should be ok nowSweitzer
The docs claim otherwise, but it seems the include directories are not inherited by subdirectories. You can test whether this is the case using a separate mini project.Peplum
Actually reading some posts looks like they do not propagate up, same for add_definitions...Sweitzer
V
29

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.
Vanesavanessa answered 15/11, 2013 at 8:59 Comment(1)
well you would want to sepcify CMAKE_CURRENT_SOURCE_DIR if you want it to be in the compile commands json if set to true.Swash
R
1

It maybe a scope problem. I feel what you are trying to do here is to propagate setting from the /project/external/foo/CMakeLists to /project/CMakeLists and such that this setting can be propagated to /project/src/CMakeLists. But unfortunately, propagation from lower-level to higher-level CMakeLists is not possible in cmake, except for cached values. This means you will also need to add include_directories(${CMAKE_SOURCE_DIR}/external/foo/include) in the /project/src/CMakeLists.txt. Or, as you already did, you can just add this line in the top-level CMakeLists.

Renovate answered 14/11, 2013 at 17:0 Comment(2)
But unfortunately, propagation from lower-level to higher-level CMakeLists is not possible in cmake, except for cached values it's not true, for regular (non-cache) variables PARENT_SCOPE can be usedJonellejones
CMAKE_SOURCE_DIR is not recommanded, use preferably CMAKE_CURRENT_SOURCE_DIR. See fujii.github.io/2015/10/10/cmake-best-practiceIntroduce

© 2022 - 2024 — McMap. All rights reserved.