【问题标题】:Including directories in Clion在 Clion 中包含目录
【发布时间】:2016-08-21 12:30:05
【问题描述】:

每当我想在 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"

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

【问题讨论】:

  • 我建议你使用像这样的目录结构 Graph/src/*.cpp , Graph/include/*.h , Dijkstra/src/*.cpp 和 Dijkstra/include/*.h .. 然后尝试 SET(GRAPH_INCLUDE_DIR Graph/include/) , SET(DIJKSTRA_INCLUDE_DIR Dijkstra/include/) INCLUDE_DIRECTORIES(${GRAPH_INCLUDE_DIR} ${DIJKSTRA_INCLUDE_DIR })
  • 根本不清楚问题。如果您使用最后一个变体并添加 include_directories(src/Graph src/Dijkstra) 会发生什么?
  • 我建议的方法是制作目录结构的更好方法。 .cpp 在一个目录中,.h 文件在另一个目录中。为什么要将这些文件混合在单个目录中。

标签: c++ cmake clion


【解决方案1】:

更新: @Tsyvarev 的回答是正确的。我已编辑此答案以删除不正确的部分并保留与target_include_directories() 相关的 cmets,但应将其视为 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 也能够将包含路径传递到您链接到该库的任何内容。听起来不多,但对于定义和链接许多库的大型项目,它可能是一个巨大的帮助。还有其他特定于目标的命令也有类似的好处。 This article 可能会让您对可能发生的事情有所了解(免责声明:我写了这篇文章)。它更侧重于target_sources(),但有关将依赖项传递到其他目标的讨论可能会有用。

【讨论】:

  • include_directories() 自动将所有相对路径转换为绝对路径。有关详细信息,请参阅documentation
  • 确实你是对的!而且我误解了这个问题(错过了使用 include_directories() 的地方)。我会把我的答案留在这里一段时间,让已经读过它的人看到我的更正,然后我会删除我的答案。谢谢指正!
【解决方案2】:

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

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

无论如何,您都需要列出add_executable()调用中的所有文件:

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

【讨论】:

    猜你喜欢
    • 2018-06-05
    • 2016-06-03
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    相关资源
    最近更新 更多