lib b depends on lib a, also installed as a standalone lib
target_link_libraries(b PUBLIC a)
dump_target_includes(b)
The dump shows that INTERFACE_INCLUDE_DIRECTORIES of a is in INCLUDE_DIRECTORIES and INTERFACE_INCLUDE_DIRECTORIES of b, no problem
app c
app c depends on lib b
find_package(b REQUIRED)
dump_target_includes(b)
The dump shows that INTERFACE_INCLUDE_DIRECTORIES of a is NOT in INCLUDE_DIRECTORIES and INTERFACE_INCLUDE_DIRECTORIES of b, and app c failed to build for it can not find header files in a.
Why do transitive dependencies from a to c break?
BTW I have used genex $<BUILD_INTERFACE:...> and $<INSTALL_INTERFACE:...> around.
OK, that wasn’t clear. The thing is that b has a link dependency on a. When CMake generates the full tree for use in a compilation line, that is when the full dependency tree is traversed and expanded. CMake cannot, in general, compute this full tree on-demand because there are ways of constructing them that depend on the target being linked. For example, this will make the include directories depend on whether an executable or library is consuming it:
The CMakeLists.txt below for app c works as expected,
i.e. INTERFACE_INCLUDE_DIRECTORIES of a is in INCLUDE_DIRECTORIES and INTERFACE_INCLUDE_DIRECTORIES of b
for comparison, the CMakeLists.txt below for app c doesn’t work as expected,
i.e. INTERFACE_INCLUDE_DIRECTORIES of a is not in INCLUDE_DIRECTORIES or INTERFACE_INCLUDE_DIRECTORIES of b
No, that’s because the include directories are added after analyzing the interface link libraries of b. It sees a in that list and then traverses it. You just cannot get the full transitive closure using genexes today (and it’s unlikely to be implemented).