每当我想在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"
。
如何正确地做到这一点以获得我想要的行为?
答案 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()
,但关于将依赖关系传递给其他目标的讨论可能会有用。