Issue
I have a quite large CMake-based project and found that while generating solution for Visual Studio on Windows I got current project home directory as an include directory. E.g. here's content of root directory:
- A
- impl
- source.cpp
- header.h
- CMakeLists.txt
- B
- CMakeLists.txt
In source.cpp
I accidentally wrote #include "header.h"
instead of #include <A/header.h>
. And such solution was successfully compiled since the directory A
for some reason was added to the list called "Additional Include Directories" in Visual Studio project (i.e. in command-line added as one more /I
option).
Same source slice gives error on Linux build similar to header.h not found
(and it's expected behavior).
Which steps should I take to find the source why does CMake adds target A's root directory to the list of include_directories
. I used the answer to print a list of project related include directories. CMake version is 3.27.1.
Solution
You may want to print the [INTERFACE_]INCLUDE_DIRECTORIES
via a custom target using generator expressions. This could allow you to go through the dependencies recursively until you find the root of the issue. This will not help you detect the use of the include_directories
command though.
print_target_info.cmake
foreach(TGT IN LISTS TARGETS)
message("---------- Target ${TGT} -----------------")
message("Interface include dirs:")
foreach(DIR IN LISTS ${TGT}_INTERFACE_INCLUDE_DIRS)
message(" - '${DIR}'")
endforeach()
message("Include dirs:")
foreach(DIR IN LISTS ${TGT}_INCLUDE_DIRS)
message(" - '${DIR}'")
endforeach()
endforeach()
CMakeLists.txt
function(add_print_target_info_command)
set(INFO)
foreach(TGT IN LISTS ARGN)
list(APPEND INFO
-D "${TGT}_INTERFACE_INCLUDE_DIRS=$<TARGET_PROPERTY:${TGT},INTERFACE_INCLUDE_DIRECTORIES>"
-D "${TGT}_INCLUDE_DIRS=$<TARGET_PROPERTY:${TGT},INCLUDE_DIRECTORIES>"
)
endforeach()
message("INFO=${INFO}")
add_custom_target(print_target_info
COMMAND
${CMAKE_COMMAND}
-D "TARGETS=${ARGN}"
${INFO}
-P ${CMAKE_CURRENT_SOURCE_DIR}/print_target_info.cmake
VERBATIM
)
endfunction()
add_print_target_info_command(
A B C D # list of the names of the targets to print the include directories for
)
This allows you to see the info in the command line output when building the target print_target_info
.
In addition you could use the --graphviz=...
option to make identifying dependencies easier, perhaps even spotting differences between both platforms
Answered By - fabian Answer Checked By - David Marino (WPSolving Volunteer)