В чем смысл ключевого слова PUBLIC
, PRIVATE
и INTERFACE
, связанного с CMake target_include_directories
?
Значение CMake target_include_directories
Ответ 1
Эти ключевые слова используются для указания , когда необходим список каталогов include, которые вы передаете цели. По , когда, это означает, что нужны те, которые содержат каталоги:
- Скомпилировать эту цель.
- Чтобы скомпилировать другие цели, которые зависят от этой цели (например, с использованием ее публичных заголовков).
- В обеих указанных ситуациях.
Когда CMake компилирует цель, он использует целевые объекты INCLUDE_DIRECTORIES
, COMPILE_DEFINITIONS
и COMPILE_OPTIONS
. Когда вы используете ключевое слово PRIVATE
в target_include_directories()
и аналогично, вы указываете CMake для заполнения этих целевых свойств.
Когда CMake обнаруживает зависимость между целью A и другой целью B (например, когда вы используете команду target_link_libraries(A B)
), она транзитно распространяет требования к использованию B
к целевому объекту A
. Эти целевые требования использования - это каталоги include, определения компиляции и т.д., Которые должны соответствовать любой цели, которая зависит от 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 в своих общедоступных файлах заголовков, которые включены в BOTH в некоторых исходных файлахA
и могут также быть включены в любой другой клиент вашей библиотекиA
.
Документация CMake 3.0 содержит более подробную информацию об этом свойствах сборки и условиях использования.
Ответ 2
Ключевые слова INTERFACE, PUBLIC и PRIVATE должны указывать область действия следующих аргументов. ЧАСТНЫЕ и ПУБЛИЧНЫЕ заполняют свойство INCLUDE_DIRECTORIES <target> . ОБЩЕСТВЕННЫЕ и Элементы INTERFACE заполнят INTERFACE_INCLUDE_DIRECTORIES свойство <target> . Следующие аргументы указывают: каталоги.
Из документации: http://www.cmake.org/cmake/help/v3.0/command/target_include_directories.html
Чтобы перефразировать документацию своими словами:
- вы хотите добавить каталог в список каталога include для целевого
- с PRIVATE каталог добавляется в целевые каталоги include
- с INTERFACE цель не изменяется, но INTERFACE_INCLUDE_DIRECTORIES расширяется каталогом. Переменная - это список общедоступных каталогов для библиотеки.
- с PUBLIC выполняются оба действия из PRIVATE и INTERFACE.