I'm trying to understand why CMake is complaining in a given situation.
I have module A depending on module B which depends on module C.
Module C is a subdir of module B, and the pertinent parts of each module's CMakeLists.txt are as shown here:
module A does:
add_library(A STATIC "")
target_include_directories(A PRIVATE
$<TARGET_PROPERTY:B,INCLUDE_DIRECTORIES>
)
module B does:
add_library(B static "")
set(some_dirs
C
)
foreach(DIR ${some_dirs})
add_subdirectory(${DIR})
target_link_libraries(B PUBLIC ${DIR})
endforeach(DIR)
module C does:
add_library(C STATIC "")
target_include_directories(C
PUBLIC
$<TARGET_PROPERTY:OtherLib,INCLUDE_DIRECTORIES>
PRIVATE
)
There is an executable that links against module A.
The reason for the use of TARGET_PROPERTY:INCLUDE_DIRECTORIES is that I am moving a large project with a lot of circular dependencies from a monolithic executable to one with distinct libraries. My initial effort is just to create the modules, then later to break the circular dependencies. So in this example, rather than target_link_libraries on the dependency, I use target_include_directories with the property INCLUDE_DIRECTORIES for the dependencies. I hope that makes sense.
I get an error with the above situation that includes:
Configuring done
Failed to parse JSON from CMake server.
Failed to parse JSON from CMake server.
CMake Error in A/CMakeLists.txt:
Found relative path while evaluating include directories of
"A":
followed by some garbage characters and some more "Failed to parse JSON from CMake server lines.
However, when I modify module C to the following:
add_library(C STATIC "")
target_include_directories(C
PUBLIC
PRIVATE
$<TARGET_PROPERTY:OtherLib,INCLUDE_DIRECTORIES>
)
The generation errors go away.
OR If I leave module C as it was originally, but change module B to this (i.e. not link against C):
add_library(B static "")
set(some_dirs
C
)
foreach(DIR ${some_dirs})
add_subdirectory(${DIR})
# target_link_libraries(B PUBLIC ${DIR})
endforeach(DIR)
and A to this:
add_library(A STATIC "")
target_include_directories(A PRIVATE
$<TARGET_PROPERTY:B,INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:C,INCLUDE_DIRECTORIES>
)
Then the generation errors also go away.
I don't quite understand why CMake thinks there are relative paths when module C uses PUBLIC vs PRIVATE inclusion. I also don't understand why the problem goes away when I remove C as a dependency of B. I do understand that IMPORTED targets can't have relative paths, but none of my targets are IMPORTED, since they are all defined within the same project.