Handling header files dependencies with cmake

You should look at the depend.make files in your binary tree. It will be in CMakeFiles/target.dir/depend.make. Try to find one of those that is missing a .h file that you think it should have. Then create a bug report for cmake or email the cmake mailing list.


I just hit the same issue. After changing paths in include_directories() from absolute to relative it added appropriate dependencies.

Looks like CMake tries to guess which headers are system and which are project related. I suspect that directories that starts with / passed as -isystem /some/path and thus are not presented in generated dependencies.

If you can't replace ${FOO_SOURCE_DIR} with relative path you can try to calculate relative path using appropriate CMake functions. I.e.:

file(RELATIVE_PATH FOO_SOURCE_REL_DIR
     ${CMAKE_CURRENT_SOURCE_DIR}
     ${FOO_SOURCE_DIR}/.)
include_directories(${FOO_SOURCE_REL_DIR}/include)

Did you run cmake before or after adding the includes to your cpp files?

I ran into this problem and re-running cmake fixed it. I'd added the include post-cmake.


Apparently cmake removes system include paths from the dependency trees (thank you @ony for this hint). This probably makes sense most of the time, but sometimes cmake doesn't know what the compiler thinks is a system path or not. We are using a custom gcc build that ignores /usr/include, but cmake thinks it doesn't ignore it. To force cmake to make /usr/include a dependency that is NOT optimized away, try this trick: prepend /. to the path.

I am trying to make all of the library dependencies use the cmake dependency feature, including certain "3rd" party libraries that are not always installed by default on Linux or even available. For example, Z-lib compression.

The following interface target worked fine if the Z lib includes were not in /usr/include, but would break if they were.

find_package(ZLIB REQUIRED)
message(status "found zlib ${ZLIB_LIBRARIES}")
message(status "found zlib includes ${ZLIB_INCLUDE_DIRS}")
target_link_libraries(zlib_target INTERFACE ${ZLIB_LIBRARIES})
target_include_directories(zlib_target INTERFACE ${ZLIB_INCLUDE_DIRS})

I changed the last line to

target_include_directories(zlib_target INTERFACE /.${ZLIB_INCLUDE_DIRS})

and it worked. Now targets that depended on zlib_target would automatically get -I/./usr/include during compilation.