cmake 找到当前目标目录作为“包含目录”添加到生成的VisualStudio项目的位置

oxf4rvwz  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(111)

我有一个相当大的基于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打印了项目相关的include目录列表。CMake版本是3.27.1。

ggazkfy8

ggazkfy81#

您可能希望使用生成器表达式通过自定义目标打印[INTERFACE_]INCLUDE_DIRECTORIES。这可以让您递归地检查依赖项,直到找到问题的根源。但是,这不会帮助您检测include_directories命令的使用。

打印目标信息.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=...选项来更轻松地识别依赖关系,甚至可能发现两个平台之间的差异。

相关问题