CMake target_include_directories значение области

Ответы:

124

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

  • Чтобы скомпилировать эту цель.
  • Для компиляции других целей, которые зависят от этой цели (например, с использованием ее общедоступных заголовков).
  • В обеих описанных выше ситуациях.

Когда CMake компилирует цель, он использует цели INCLUDE_DIRECTORIES, COMPILE_DEFINITIONSи COMPILE_OPTIONSсвойство. Когда вы используете PRIVATEключевое слово in target_include_directories()и ему подобные, вы указываете CMake заполнить эти целевые свойства.

Когда CMake обнаруживает зависимость между целью A и другой целью B (например, когда вы используете target_link_libraries(A B)команду), он транзитивно распространяет B требования использования на Aцель. Эти требования к целевому использованию - это каталоги включения, определения компиляции и т.д., которым Bдолжна соответствовать любая цель, от которой зависит . Они определяются INTERFACE_*версией перечисленных выше свойств (например, INTERFACE_INCLUDE_DIRECTORIES) и заполняются с помощью INTERFACEключевого слова при вызове target_*()команд.

PUBLICКлючевое слово означает примерно PRIVATE + INTERFACE.

Поэтому предположим, что вы создаете библиотеку, Aкоторая использует некоторые заголовки Boost. Вы бы сделали:

  • target_include_directories(A PRIVATE ${Boost_INCLUDE_DIRS})если вы используете эти заголовки Boost только внутри исходных файлов ( .cpp) или частных файлов заголовков ( .h).
  • target_include_directories(A INTERFACE ${Boost_INCLUDE_DIRS})если вы не используете эти заголовки Boost в исходных файлах (следовательно, они не требуются для компиляции A). На самом деле я не могу придумать для этого реальный пример.
  • target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})если вы используете эти заголовки Boost в своих общедоступных файлах заголовков, которые включены ОБЕИХ в некоторые Aисходные файлы, а также могут быть включены в любой другой клиент вашей Aбиблиотеки.

В документации CMake 3.0 есть более подробная информация об этой спецификации сборки и свойствах требований к использованию .

TManhente
источник
18
Что касается реального примера INTERFACE. target_include_directories(libname INTERFACE include PRIVATE include/libname). Это означает, что в вашу библиотеку вы можете напрямую включать файлы, но как пользователь библиотеки вы должны libname/сначала вставить их .
KaareZ
2
Эти ответы имеют смысл для меня при создании библиотек. Но как насчет вызова target_include_directories для цели, которая является исполняемым файлом?
Норман Пелле,
1
@NormanPellet: вы можете вызвать target_include_directories()исполняемую цель, если вам нужно установить каталоги включения, в которых должны быть найдены файлы заголовков, которые используются этими исполняемыми файлами (например: Boost :: Program_options, если вы используете его для анализа аргументов в своей main()функции) . В этом случае вы, вероятно, использовали бы PRIVATEключевое слово, так как эти файлы необходимы для компиляции самого исполняемого файла. Однако я не знаю, есть ли какое-то применение для исполняемого файла INTERFACEили PUBLICот него.
TManhente
13

Ключевые слова INTERFACE, PUBLIC и PRIVATE необходимы для определения области действия следующих аргументов. Элементы PRIVATE и PUBLIC заполнят свойство INCLUDE_DIRECTORIES <target>. Элементы PUBLIC и INTERFACE заполнят свойство INTERFACE_INCLUDE_DIRECTORIES <target>. Следующие аргументы указывают подключаемые каталоги.

Из документации: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html

Перефразируя документацию своими словами:

  • вы хотите добавить каталог в список включаемых каталогов для цели
  • с PRIVATE каталог добавляется в целевые каталоги include
  • с INTERFACE цель не изменяется, но INTERFACE_INCLUDE_DIRECTORIES расширяется каталогом. Переменная представляет собой список общедоступных подключаемых каталогов для библиотеки.
  • с PUBLIC выполняются оба действия из PRIVATE и INTERFACE.
usr1234567
источник
5
Я просмотрел документацию CMAKE, но так и не понял, что они на самом деле означают и в каком контексте (создавать файлы или как они компилируются)?
Sirish
@Sirish: Я попытался перефразировать документацию, надеюсь, что это поможет.
usr1234567