Reputation: 4273
Whenever I wanted to include a directory that was located outside of my project with Clion I would use the -I somedir
flag. This time however, what I want to do is to have a hierarchy like this:
/project
CMakeLists.txt
/src
/Graph
Graph.h
Graph.cpp
/Dijkstra
Dijkstra.h
Dijstra.cpp
I want my code in a /src
directory. And not only that, but also, for example, inside the file Dijkstra.h
I want to include the Graph.h like this: #include "Graph/Graph.h
and not like this: #include "../Graph/Graph.h
.
If I only add an -I src
flag, then if I am inside the Dijkstra.h
file and I wanted to include Graph.h
, I would have to write #include "../Graph/Graph.h
, which is not what I want.
So I tried to also add INCLUDE_DIRECTORIES(src)
. That fixed the problem above, however when tried to compiled, I got a linker error undefined reference to...
.
So I tried adding the files one by one like this:
set(SOURCE_FILES
src/Dijkstra/Dijkstra.h
src/Dijkstra/Dijkstra.cpp
src/Graph/Graph.h
src/Graph/Graph.cpp)
add_executable(someprojectname ${SOURCE_FILES})
and that brought back the previous problem, where I had to include the files like this: #include "../Graph/Graph.h"
.
How can I do this properly to get the behavior I want ?
Upvotes: 7
Views: 27523
Reputation: 10137
UPDATE: @Tsyvarev's answer is correct. I've edited this answer to remove the incorrect part and keep the comments relating to target_include_directories()
, but it should be viewed as additional to Tsyvarev's answer.
INCLUDE_DIRECTORIES(src)
will make the src
directory get added as a search path to all targets defined from that point on. It does not add sources to any targets. The search path will be relative to the current source directory and CMake will adjust it as appropriate when descending into subdirectories via add_subdirectory()
. While this is fine if that's what you want, as the project gets bigger and more complicated, you may find you would prefer to apply the include path settings to just some targets. For that, use target_include_directories()
instead:
target_include_directories(someprojectname "${CMAKE_CURRENT_SOURCE_DIR}/src")
This will have the same effect, but it restricts the use of the added include path to just the someprojectname
target. If you later define some other target which doesn't need the include path, it won't be added. This can help prevent situations like unexpected files being picked up if you have deep directory hierarchies and you re-use directory names in different places, for example).
The target_include_directories()
command has additional benefits when applied to library targets because CMake has the ability to carry the include path through to anything you link against that library too. Doesn't sound like much, but for large projects which define and link many libraries, it can be a huge help. There are other target-specific commands which have similar benefits too. This article may give you a bit of a feel for what is possible (disclaimer: I wrote the article). It is more focused on target_sources()
, but the discussion around carrying dependencies through to other targets may be useful.
Upvotes: 4
Reputation: 65870
Command INCLUDE_DIRECTORIES
doesn't add any source file for compile!
Instead, this command defines directories for search header files.
You need to list all source files in add_executable()
call in any case:
include_directories(src)
set(SOURCE_FILES
src/Dijkstra/Dijkstra.cpp
src/Graph/Graph.cpp)
add_executable(someprojectname ${SOURCE_FILES})
Upvotes: 7