在Clion

时间:2016-04-27 09:37:26

标签: c++ cmake 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"

如何正确地做到这一点以获得我想要的行为?

2 个答案:

答案 0 :(得分:5)

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

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

在任何情况下,您都需要在add_executable()来电中列出所有来源文件:

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

答案 1 :(得分:2)

更新: @ 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还能够将包含路径传递到您链接到该库的任何内容。听起来不是很多,但对于定义和链接许多库的大型项目来说,这可能是一个巨大的帮助。还有其他特定于目标的命令也具有类似的好处。 This article可能会让你对可能的事情有所了解(免责声明:我写了这篇文章)。它更侧重于target_sources(),但关于将依赖关系传递给其他目标的讨论可能会有用。