在 Clion 中包含目录

Including directories in Clion

每当我想使用 Clion 包含一个位于我的项目之外的目录时,我都会使用 -I somedir 标志。然而这一次,我想要做的是拥有这样的层次结构:

/project
   CMakeLists.txt
   /src
      /Graph
         Graph.h
         Graph.cpp
      /Dijkstra
         Dijkstra.h
         Dijstra.cpp

我希望我的代码在 /src 目录中。不仅如此,而且,例如,在文件 Dijkstra.h 中,我想像这样包含 Graph.h:#include "Graph/Graph.h 而不是这样:#include "../Graph/Graph.h.

如果我只添加一个 -I src 标志,那么如果我在 Dijkstra.h 文件中并且我想包含 Graph.h,我将不得不写 #include "../Graph/Graph.h ,这不是我想要的。

所以我也尝试添加 INCLUDE_DIRECTORIES(src)。这解决了上面的问题,但是当尝试编译时,我得到了一个链接器错误 undefined reference to....

所以我尝试像这样一个一个地添加文件:

set(SOURCE_FILES
        src/Dijkstra/Dijkstra.h
        src/Dijkstra/Dijkstra.cpp
        src/Graph/Graph.h
        src/Graph/Graph.cpp)
add_executable(someprojectname ${SOURCE_FILES})

这又回到了之前的问题,我不得不像这样包含文件:#include "../Graph/Graph.h"

我怎样才能正确地做到这一点以获得我想要的行为?

更新: @Tsyvarev 的回答是正确的。我已经编辑了这个答案以删除不正确的部分并保留与 target_include_directories() 相关的评论,但它应该被视为 Tsyvarev 答案的补充。

INCLUDE_DIRECTORIES(src) 将使 src 目录作为搜索路径添加到从该点开始定义的所有目标。它不会将源添加到任何目标。搜索路径将相对于当前源目录,当通过 add_subdirectory() 下降到子目录时,CMake 将适当调整它。虽然这很好,如果这是您想要的,但随着项目变得越来越大和越来越复杂,您可能会发现您更愿意将包含路径设置应用于某些目标。为此,请改用 target_include_directories()

target_include_directories(someprojectname "${CMAKE_CURRENT_SOURCE_DIR}/src")

这将具有相同的效果,但它将添加的包含路径的使用限制为仅 someprojectname 目标。如果您稍后定义了一些不需要包含路径的其他目标,则不会添加它。这有助于防止出现意外文件被拾取的情况,例如,如果您的目录层次结构很深并且在不同的地方重复使用目录名称)。

target_include_directories() 命令在应用于库目标时具有额外的好处,因为 CMake 能够将包含路径传递给您 link 针对该库的任何内容。听起来不多,但对于定义和 link 许多库的大型项目来说,这可能是一个巨大的帮助。还有其他特定于目标的命令也有类似的好处。 This article 可能会让您对什么是可能的有所了解(免责声明:我写了这篇文章)。它更侧重于 target_sources(),但围绕将依赖项传递到其他目标的讨论可能会有用。

命令INCLUDE_DIRECTORIES 不添加任何源文件进行编译!

相反,此命令为搜索头文件定义了目录。

在任何情况下,您都需要在 add_executable() 调用中列出所有 source 文件:

include_directories(src)
set(SOURCE_FILES
    src/Dijkstra/Dijkstra.cpp
    src/Graph/Graph.cpp)
add_executable(someprojectname ${SOURCE_FILES})