我有一个相当大的基于 CMake 的项目,发现在 Windows 上为 Visual Studio 生成解决方案时,我将当前项目主目录作为包含目录。例如。这是根目录的内容:
- A
- impl
- source.cpp
- header.h
- CMakeLists.txt
- B
- CMakeLists.txt
在
source.cpp
中我不小心写了#include "header.h"
而不是#include <A/header.h>
。并且这样的解决方案已成功编译,因为目录 A
由于某种原因被添加到 Visual Studio 项目中名为“其他包含目录”的列表中(即在命令行中添加为另一个 /I
选项)。
相同的源切片在 Linux 构建上给出类似于
header.h not found
的错误(这是预期的行为)。
我应该采取哪些步骤来查找源代码为什么CMake将目标A的根目录添加到
include_directories
的列表中。我使用 answer 打印项目相关包含目录的列表。 CMake 版本是 3.27.1.
您可能希望使用生成器表达式通过自定义目标打印
[INTERFACE_]INCLUDE_DIRECTORIES
。这可以让您递归地检查依赖关系,直到找到问题的根源。但这不会帮助您检测 include_directories
命令的使用。
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
)
这允许您在构建目标时查看命令行输出中的信息
print_target_info
。
--graphviz=...
选项 来更轻松地识别依赖关系,甚至可能发现两个平台之间的差异