Как правильно добавить включаемые каталоги с CMake
Около года назад я спросил о зависимостях заголовка в CMake.
Недавно я понял, что проблема заключается в том, что CMake считает эти файлы заголовков внешними по отношению к проекту. По крайней мере, при генерации проекта Code :: Blocks заголовочные файлы не появляются внутри проекта (исходные файлы делают). Поэтому мне кажется, что CMake считает эти заголовки внешними по отношению к проекту и не отслеживает их в зависимости.
Быстрый поиск в учебнике по CMake только указал на include_directories
который, кажется, не делает то, что я хочу...
Как правильно сообщить CMake, что конкретный каталог содержит заголовки, которые необходимо включить, и что эти заголовки должны отслеживаться сгенерированным Makefile?
Ответы
Ответ 1
Две вещи должны быть сделаны.
Сначала добавьте каталог, который будет включен:
target_include_directories(test PRIVATE ${YOUR_DIRECTORY})
В случае, если вы застряли с очень старой версией CMake (2.8.10 или более старой) без поддержки target_include_directories
, вы также можете использовать устаревшие include_directories
:
include_directories(${YOUR_DIRECTORY})
Затем вы также должны добавить файлы заголовков в список ваших исходных файлов для текущей цели, например:
set(SOURCES file.cpp file2.cpp ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_executable(test ${SOURCES})
Таким образом, файлы заголовков будут отображаться как зависимости в Makefile, а также, например, в сгенерированном проекте Visual Studio, если вы его сгенерируете.
Как использовать эти заголовочные файлы для нескольких целей:
set(HEADER_FILES ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_library(mylib libsrc.cpp ${HEADER_FILES})
target_include_directories(mylib PRIVATE ${YOUR_DIRECTORY})
add_executable(myexec execfile.cpp ${HEADER_FILES})
target_include_directories(myexec PRIVATE ${YOUR_DIRECTORY})
Ответ 2
Во-первых, вы используете include_directories()
чтобы указать CMake добавить каталог как -I
в командную строку компиляции. Во-вторых, вы перечисляете заголовки в вашем add_executable()
или add_library()
.
Например, если ваши источники проекта находятся в src
, и вам нужны заголовки из include
, вы можете сделать это следующим образом:
include_directories(include)
add_executable(MyExec
src/main.c
src/other_source.c
include/header1.h
include/header2.h
)
Ответ 3
CMake больше похож на язык сценариев, если сравнивать его с другими способами создания Makefile (например, make или qmake). Это не очень круто, как Python, но все же.
Нет такого понятия, как "правильный путь", если смотреть в различных проектах с открытым исходным кодом, как люди включают каталоги. Но есть два способа сделать это.
-
Crude include_directories добавит каталог в текущий проект и все другие проекты-потомки, которые вы добавите с помощью ряда команд add_subdirectory. Иногда люди говорят, что такой подход является наследием.
-
Более элегантный способ - с target_include_directories. Это позволяет добавить каталог для конкретного проекта/цели без (может быть) ненужного наследования или столкновения различных включаемых каталогов. Также позвольте выполнить даже тонкую настройку и добавьте один из следующих маркеров для этой команды.
PRIVATE - использовать только для указанной цели сборки
PUBLIC - используйте его для указанной цели и для целей, которые связаны с этим проектом
ИНТЕРФЕЙС - используйте его только для целей, которые связаны с текущим проектом
PS:
-
Обе команды позволяют пометить каталог как SYSTEM, чтобы дать подсказку, что это не ваша компания, что указанные каталоги будут содержать предупреждения.
-
Аналогичный ответ с другими парами команд target_compile_definitions/add_definitions, target_compile_options/CMAKE_C_FLAGS
Ответ 4
У меня такая же проблема.
Моя директория проекта была такой:
--project
---Classes
----Application
-----.h and .c files
----OtherFolders
--main.cpp
И что я использовал, чтобы включить файлы во всех этих папках:
file(GLOB source_files
"*.h"
"*.cpp"
"Classes/*/*.cpp"
"Classes/*/*.h"
)
add_executable(Server ${source_files})
И это полностью сработало.
Ответ 5
Добавьте include_directories("/your/path/here")
.
Это будет похоже на вызов gcc
с -I/your/path/here/
.
Убедитесь, что вы поместили двойные кавычки вокруг пути. Другие люди не упоминали об этом, и это заставило меня застрять на 2 дня. Таким образом, этот ответ для людей, которые очень плохо знакомы с CMake и очень смущены.