Разница между (target_)link_libraries и (target_)include_directories

Я борюсь с большим проектом C++, который использует CMake. Теперь я пытаюсь добавить зависимость (предварительно скомпилированную и установленную библиотеку), но я не уверен, где это добавить, что включить и где это связать.

В частности, я хотел бы знать разницу между следующими командами:

  • include_directories
  • target_include_directories
  • link_libraries
  • target_link_libraries

Кроме того, когда мне нужно использовать следующие команды:

  • find_package и
  • add_library

Я знаю, что это как-то связано с библиотеками только для заголовков и т. д., но я не смог найти понятного и сжатого объяснения.

Кроме того, как мне поступить в следующем случае:

Включенная библиотека требует, например, Boost, а основной проект — нет. Как избежать раздувания всего файла CMakeLists.txt и двоичных файлов и при этом использовать предварительно скомпилированную библиотеку? (Я думаю, что это тоже часть этого вопроса)


person Dorian    schedule 12.06.2019    source источник
comment
Слишком много вопросов в одном сообщении. Например. разницу между include_directories и target_include_directories можно найти в этом вопросе: directory" title="в чем разница между каталогами включения и целевым каталогом включения"> stackoverflow.com/questions/31969547/   -  person Tsyvarev    schedule 12.06.2019


Ответы (1)


*include_directories используется для предоставления компилятору списка включаемых каталогов. Когда файл включается с помощью препроцессора, в этих каталогах будет выполняться поиск файла.

*link_libraries используется для предоставления компоновщику списка библиотек (архивов объектов). Если связанный элемент является целью cmake с указанными включаемыми каталогами, их не нужно указывать отдельно с помощью *include_directories.

Версии target_* применяются только к цели, заданной в качестве операнда. Нецелевые версии применяются ко всем целям в каталоге. Версии target_* следует использовать везде, где это возможно (т. е. почти всегда).

find_package используется для поиска настроек cmake из внешних источников, то есть вне проекта. Если вы хотите связать библиотеку без включения исходного кода библиотеки в подкаталог вашего проекта, используйте find_package. С точки зрения нижнего уровня find_package(Foo) ищет модуль cmake FindFoo.cmake и выполняет этот модуль. Цель модуля — генерировать переменные или цели cmake, которые можно использовать для включения соответствующей зависимости.

add_library похож на add_executable, за исключением того, что он добавляет цель для библиотеки, а не для исполняемого файла. Цели библиотеки могут использоваться как элементы в link_libraries, а их зависимости по умолчанию транзитивны.

Я знаю, что это как-то связано с библиотеками только для заголовков и так далее,

Все это связано с библиотеками в целом. За исключением того, что *include_directories также используются для указания каталога включения собственных заголовочных файлов проекта, а не только файлов библиотек.


Включенная библиотека требует, например, Boost, а основной проект — нет. Как избежать раздувания всего файла CMakeLists.txt и двоичных файлов и при этом использовать предварительно скомпилированную библиотеку?

Если модуль find_package создал цель cmake для библиотеки (используя add_library(... IMPORTED)), которая сама определяет зависимости зависимости, то просто свяжите ее с помощью link_libraries, а cmake позаботится о связывании с зависимостями. . То же самое касается включаемого каталога цели.

Старые модули cmake не обязательно предоставляют цели, и в этом случае вам может потребоваться написать собственный модуль, чтобы избежать раздувания конфигурации проекта.

person eerorika    schedule 12.06.2019
comment
Незначительное дополнение: find_package(Foo) также может использовать файлы в таких местах, как /usr/lib/cmake/Foo/FooConfig.cmake — такие файлы обычно предоставляются внешним пакетом, а не FindFoo.cmake, который предоставляется проектом. - person Daniel Schepler; 12.06.2019