在 Clion 中包含目录
Including directories in 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"
。
我怎样才能正确地做到这一点以获得我想要的行为?
更新: @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 能够将包含路径传递给您 link 针对该库的任何内容。听起来不多,但对于定义和 link 许多库的大型项目来说,这可能是一个巨大的帮助。还有其他特定于目标的命令也有类似的好处。 This article 可能会让您对什么是可能的有所了解(免责声明:我写了这篇文章)。它更侧重于 target_sources()
,但围绕将依赖项传递到其他目标的讨论可能会有用。
命令INCLUDE_DIRECTORIES
不添加任何源文件进行编译!
相反,此命令为搜索头文件定义了目录。
在任何情况下,您都需要在 add_executable()
调用中列出所有 source 文件:
include_directories(src)
set(SOURCE_FILES
src/Dijkstra/Dijkstra.cpp
src/Graph/Graph.cpp)
add_executable(someprojectname ${SOURCE_FILES})
每当我想使用 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"
。
我怎样才能正确地做到这一点以获得我想要的行为?
更新: @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 能够将包含路径传递给您 link 针对该库的任何内容。听起来不多,但对于定义和 link 许多库的大型项目来说,这可能是一个巨大的帮助。还有其他特定于目标的命令也有类似的好处。 This article 可能会让您对什么是可能的有所了解(免责声明:我写了这篇文章)。它更侧重于 target_sources()
,但围绕将依赖项传递到其他目标的讨论可能会有用。
命令INCLUDE_DIRECTORIES
不添加任何源文件进行编译!
相反,此命令为搜索头文件定义了目录。
在任何情况下,您都需要在 add_executable()
调用中列出所有 source 文件:
include_directories(src)
set(SOURCE_FILES
src/Dijkstra/Dijkstra.cpp
src/Graph/Graph.cpp)
add_executable(someprojectname ${SOURCE_FILES})