Handling header files dependencies with cmake

Matthieu M. picture Matthieu M. · Sep 18, 2011 · Viewed 56.8k times · Source

I am using CMake on a small C++ project and so far it works great... with one twist :x

When I change a header file, it typically requires recompiling a number of sources files (those which include it, directly or indirectly), however it seems that cmake only detects some of the source files to be recompiled, leading to a corrupted state. I can work around this by wiping out the project and rebuilding from scratch, but this circumvents the goal of using a make utility: only recompiling what is needed.

Therefore, I suppose I am doing something wrong.

My project is very simply organized:

  • a top directory where all resources sit, the main CMakeLists.txt sits there
  • a "include" directory where all public headers lies (in various subdirectories)
  • a "src" directory where all the subdirectories for sources files are, the src CMakeLists.txt sits there
  • a CMakeLists.txt per subdirectory in the "src" directory

The main directory has:

cmake_minimum_required(VERSION 2.8)

project(FOO)

set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)

# Compiler Options
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++0x -Wall -Wextra -Werror")

include_directories($(FOO_SOURCE_DIR)/include)

add_subdirectory(src)

The "src" directory:

add_subdirectory(sub1)
add_subdirectory(sub2)
add_subdirectory(sub3)
add_subdirectory(sub4)

add_executable(foo main.cpp)

target_link_libraries(foo sub1 sub2 sub3 sub4)

Where sub4 depends on sub3 which depends on sub2 which depends on sub1

And an example of a subdirectory (sub3):

set(SUB3_SRCS
    File1.cpp
    File2.cpp
    File3.cpp
    File4.cpp
    File5.cpp
    File6.cpp
    )

add_library(sub3 ${SUB3_SRCS})

target_link_libraries(sub3 sub1 sub2)

I'd be glad if anyone could point my mistake to me, searching here or on CMake didn't yield anything so I guess it's very easy or should work out of the box...

(for reference, I am using cmake version 2.8.2 on MSYS)

EDIT:

Thanks to Bill's suggestion I have checked the depend.make file generated by CMake, and it is indeed lacking (severely). Here is an example:

src/sub3/CMakeFiles/sub3.dir/File1.cpp.obj: ../src/sub3/File1.cpp

Yep, that's all, non of the includes were referenced at all :x

Answer

Bill Hoffman picture Bill Hoffman · Sep 21, 2011

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.