Включение каталогов в 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".

Как я могу сделать это правильно, чтобы получить поведение, которое я хочу?


person dimitris93    schedule 27.04.2016    source источник
comment
я бы посоветовал вам использовать такую ​​структуру каталогов, как Graph/src/*.cpp, Graph/include/*.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})   -  person Varun    schedule 27.04.2016
comment
Вообще не понятный вопрос. Если вы используете последний вариант и добавляете include_directories(src/Graph src/Dijkstra), что произойдет?   -  person fghj    schedule 27.04.2016
comment
Способ, который я предложил, лучше всего подходит для создания структуры каталогов. .cpp в одном каталоге и файл .h в другом каталоге. Зачем смешивать эти файлы в одном каталоге.   -  person Varun    schedule 27.04.2016


Ответы (2)


Команда INCLUDE_DIRECTORIES не добавляет никакого исходного файла для компиляции!

Вместо этого эта команда определяет каталоги для файлов заголовков поиска.

В любом случае вам необходимо перечислить все исходные файлы в вызове add_executable():

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

ОБНОВЛЕНИЕ: ответ @Tsyvarev правильный. Я отредактировал этот ответ, чтобы удалить неправильную часть и сохранить комментарии, относящиеся к target_include_directories(), но его следует рассматривать как дополнение к ответу Цыварева.

INCLUDE_DIRECTORIES(src) сделает так, что каталог src будет добавлен в качестве пути поиска для всех целей, определенных с этого момента. Он не добавляет источники ни к каким целям. Путь поиска будет относиться к текущему исходному каталогу, и CMake соответствующим образом скорректирует его при переходе в подкаталоги через add_subdirectory(). Хотя это нормально, если это то, что вы хотите, по мере того, как проект становится больше и сложнее, вы можете обнаружить, что предпочитаете применять настройки пути включения только к некоторым целям. Для этого используйте вместо этого target_include_directories():

target_include_directories(someprojectname "${CMAKE_CURRENT_SOURCE_DIR}/src")

Это будет иметь тот же эффект, но ограничивает использование добавленного пути включения только целью someprojectname. Если позже вы определите какую-либо другую цель, для которой не требуется путь включения, она не будет добавлена. Это может помочь предотвратить такие ситуации, как получение неожиданных файлов, например, если у вас есть глубокая иерархия каталогов и вы повторно используете имена каталогов в разных местах).

Команда target_include_directories() имеет дополнительные преимущества при применении к целевым объектам библиотеки, поскольку CMake имеет возможность перенести путь включения на все, что вы связываете с этой библиотекой. Звучит не очень, но для больших проектов, которые определяют и связывают множество библиотек, это может быть огромным подспорьем. Существуют и другие команды для конкретных целей, которые также имеют аналогичные преимущества. Эта статья может дать вам немного ощущение того, что возможно (отказ от ответственности: я написал статью). Он больше сосредоточен на target_sources(), но обсуждение переноса зависимостей на другие цели может быть полезным.

person Craig Scott    schedule 27.04.2016
comment
include_directories() автоматически преобразует все относительные пути в абсолютные. Дополнительные сведения см. в документации. - person Tsyvarev; 27.04.2016
comment
Ведь вы правы! И я неправильно понял вопрос (пропустил, где использовалось include_directories()). Я оставлю свой ответ здесь на некоторое время, чтобы те, кто уже прочитал его, увидели мое исправление, затем я удалю свой ответ. Спасибо за исправление! - person Craig Scott; 27.04.2016