2016-04-27 101 views
5

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

/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"

我该怎么做才能得到我想要的行为?

+0

我建议,您使用的目录结构类似这样的图形/ src目录/ * CPP,图形/包括/ * .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

+0

根本不清楚问题。如果使用最后一个变体并添加'include_directories(src/Graph src/Dijkstra)'会发生什么? – fghj

+0

我建议的方式是制作目录结构的更好方法。 .cpp放在一个目录中,而.h文件放在另一个目录中。为什么要在单个目录中混合这些文件。 – Varun

回答

5

命令INCLUDE_DIRECTORIES不添加用于编译任何源文件

取而代之的是,该命令为搜索头文件定义了目录。

你需要列出所有add_executable()通话文件在任何情况下:

include_directories(src) 
set(SOURCE_FILES 
    src/Dijkstra/Dijkstra.cpp 
    src/Graph/Graph.cpp) 
add_executable(someprojectname ${SOURCE_FILES}) 
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(),但围绕其他目标进行依赖关系的讨论可能会有用。

+0

'include_directories()** **自动**将所有相对路径转换为绝对路径。有关更多详细信息,请参见[文档](https://cmake.org/cmake/help/v3.0/command/include_directories.html)。 – Tsyvarev

+0

确实你是对的!我误解了这个问题(错过了include_directories()被使用的地方)。我会在这里留下我的答案一段时间,让已经阅读过它的人看到我的更正,然后我会删除我的答案。感谢您的更正! –