Какой смысл ключевого слова PUBLIC
, PRIVATE
и INTERFACE
связанный с CMake - х target_include_directories
?
Ответы:
Эти ключевые слова используются, чтобы указать, когда нужен список включаемых каталогов, который вы передаете целевой папке. К , когда , это означает , что, если таковые необходимы , включают каталоги:
Когда 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 есть более подробная информация об этой спецификации сборки и свойствах требований к использованию .
INTERFACE
. target_include_directories(libname INTERFACE include PRIVATE include/libname)
. Это означает, что в вашу библиотеку вы можете напрямую включать файлы, но как пользователь библиотеки вы должны libname/
сначала вставить их .
target_include_directories()
исполняемую цель, если вам нужно установить каталоги включения, в которых должны быть найдены файлы заголовков, которые используются этими исполняемыми файлами (например: Boost :: Program_options, если вы используете его для анализа аргументов в своей main()
функции) . В этом случае вы, вероятно, использовали бы PRIVATE
ключевое слово, так как эти файлы необходимы для компиляции самого исполняемого файла. Однако я не знаю, есть ли какое-то применение для исполняемого файла INTERFACE
или PUBLIC
от него.
Ключевые слова 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
Перефразируя документацию своими словами: