查找将当前目标目录作为“包含目录”添加到生成的 Visual Studio 项目的位置

Find the place where the current target directory is added as "include directory" to generated Visual Studio project

提问人:αλεχολυτ 提问时间:8/4/2023 更新时间:8/4/2023 访问量:44

问:

我有一个相当大的基于 CMake 的项目,发现在 Windows 上为 Visual Studio 生成解决方案时,我获得了当前项目主目录作为包含目录。例如,这是根目录的内容:

- A
   - impl
     - source.cpp
   - header.h
   - CMakeLists.txt
- B
- CMakeLists.txt

在我不小心写了而不是.并且由于某种原因将目录添加到Visual Studio项目中名为“其他包含目录”的列表中(即在命令行中添加为另一个选项),因此该解决方案已成功编译。source.cpp#include "header.h"#include <A/header.h>A/I

相同的源切片在 Linux 构建上给出错误,类似于(这是预期行为)。header.h not found

我应该采取哪些步骤来查找源,为什么 CMake 将目标 A 的根目录添加到 .我使用答案打印了与项目相关的包含目录列表。CMake 版本为 3.27.1。include_directories

C++ cmake include 包含路径

评论

0赞 Alan Birtles 8/4/2023
你设置 cmake.org/cmake/help/latest/variable/ 吗?
1赞 john 8/4/2023
在 Visual Studio 中,将在当前目录中搜索任何包含引号的文件。AFAIK 您不能更改此设置,除非将引号更改为 .<>
0赞 fabian 8/4/2023
@john 如果“当前目录”是指包含带有指令的文件的目录:这不是 VS 特定的行为,而是标准行为......#include "..."
0赞 starball 8/5/2023
@fabian定义“标准”。我以为它是实现定义的。
0赞 αλεχολυτ 8/9/2023
@starball标准它是实现定义的。

答:

1赞 fabian 8/4/2023 #1

您可能希望使用生成器表达式打印通过自定义目标。这可以让你以递归方式遍历依赖项,直到找到问题的根源。但是,这不会帮助您检测命令的使用情况。[INTERFACE_]INCLUDE_DIRECTORIESinclude_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=... 选项来更轻松地识别依赖关系,甚至可以发现两个平台之间的差异

评论

0赞 αλεχολυτ 8/8/2023
谢谢你的回答。实际上,我通过在顶层的CMake相关文件中查找找到了问题的根源,并找到了带有操作数的罪魁祸首调用。include_directoriesCMAKE_CURRENT_SOURCE_DIR