在Clion中包含目录

7

每当我想在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})。 - Varun
问题非常不清楚。 如果您使用最后一种变体并添加include_directories(src / Graph src / Dijkstra),会发生什么? - fghj
我建议的方式是更好的建立目录结构。将.cpp文件放在一个目录中,将.h文件放在另一个目录中。为什么要把这些文件混合在一个目录中呢? - Varun
2个回答

7

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

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

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

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

4

更新: @Tsyvarev的答案是正确的。我编辑了这个答案以删除不正确的部分,并保留与target_include_directories()相关的注释,但它应该被视为额外的附加内容。

INCLUDE_DIRECTORIES(src)将把src目录添加为从此点定义的所有目标的搜索路径。它不会向任何目标添加源文件。搜索路径将相对于当前源目录,并且当通过add_subdirectory()进入子目录时,CMake会适当地调整它。如果这正是您想要的,那么这很好,但随着项目变得越来越大和复杂,您可能会发现您更喜欢仅将包含路径设置应用于某些目标。为此,请改用target_include_directories()

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

这将产生相同的效果,但它限制了添加的包含路径仅适用于someprojectname目标。如果您稍后定义了其他不需要包含路径的目标,则不会添加它。这可以帮助防止出现意外文件被捡起的情况,例如您在不同的地方重复使用目录名称并且具有深层目录层次结构。 target_include_directories()命令在应用于库目标时具有附加优点,因为CMake有能力将包含路径传递到您链接到该库的任何内容中。听起来不像什么,但对于定义和链接许多库的大型项目而言,它可以提供巨大的帮助。还有其他具有类似优点的目标特定命令。 本文可能会让您对可能性有些了解(免责声明:我写了这篇文章)。它更侧重于target_sources(),但围绕将依赖项传递到其他目标的讨论可能会有所帮助。

include_directories()函数会自动将所有相对路径转换为绝对路径。更多详情请参考文档 - Tsyvarev
确实,你是正确的!我误解了问题(错过了include_directories()的使用位置)。我会将我的答案保留一段时间,以便那些已经阅读它的人看到我的更正,然后我会删除我的答案。感谢你的纠正! - Craig Scott

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接